junit 跳过测试

    技术2024-01-09  105

    在你开始前

    关于本教程

    Java 5注释的引入给JUnit带来了巨大的变化,使JUnit从开发人员已经广为人知和喜爱的测试框架转变为更加精简却不那么熟悉的东西。 在本教程中,我将讨论对JUnit 4的最重要更改,并介绍您可能已经听说过但可能尚未使用的令人兴奋的新功能。

    目标

    本教程将逐步指导您了解JUnit 4的基本概念,并重点介绍新的Java 5批注。 在这个1小时的教程结束时,您将了解JUnit 4的主要更改,并熟悉诸如异常测试,参数测试和新的灵活的夹具模型等功能。 您将知道如何声明测试,如何在运行测试之前使用批注(而不是套件)对测试进行逻辑分组,如何在Eclipse 3.2或Ant中以及从命令行运行测试。

    先决条件

    为了从本教程中获得最大收益,您应该总体上熟悉Java开发。 本教程还假定您了解开发人员测试的价值,并且熟悉基本的模式匹配。 要遵循有关运行JUnit 4测试的部分,您应该能够将Eclipse 3.2作为IDE并与Ant 1.6或更高版本一起使用。 您无需熟悉JUnit的早期版本即可学习本教程。

    系统要求

    要继续进行并尝试本教程的代码,您需要有效安装Sun的JDK 1.5.0_09(或更高版本)或Java技术1.5.0 SR3的IBM开发人员工具包。 对于在Eclipse中运行JUnit 4的部分,您需要有效安装Eclipse 3.2或更高版本。 对于有关Ant的部分,您需要版本1.6或更高版本。

    本教程推荐的系统配置如下:

    系统支持Sun JDK 1.5.0_09(或更高版本)或Java技术1.5.0 SR3的IBM开发人员套件,且主内存至少为500MB 至少20MB的磁盘空间用于安装软件组件和示例

    本教程中的说明基于Microsoft Windows操作系统。 本教程中介绍的所有工具也可以在Linux和UNIX系统上使用。

    JUnit 4的新增功能

    感谢Java 5注释,JUnit 4比以往任何时候都更加轻巧和灵活。 它放弃了严格的命名约定和继承层次结构,而使用了一些令人兴奋的新功能。 以下是JUnit 4新增功能的快速列表:

    参数测试 异常测试 超时测试 灵活的夹具 一种忽略测试的简单方法 一种逻辑上对测试进行分组的新方法

    首先,我将解释对JUnit 4的最重要,最重要的更改,以准备在后面的部分中介绍这些功能以及更多新功能。

    与旧

    在JUnit 4中添加Java 5注释之前,该框架已经建立了两个约定,这些约定对其功能至关重要。 首先是JUnit隐式要求编写的任何用作逻辑测试的方法均以单词test开头。 以该词开头的任何方法(例如testUserCreate )都将根据定义明确的测试过程执行,以确保在测试方法之前和之后都执行固定装置。 其次,为了让JUnit识别包含测试的类对象,需要从JUnit的TestCase (或其某些派生类)扩展该类本身。 违反这两个约定之一的测试将不会运行 。

    清单1显示了在JUnit 4之前编写的JUnit测试。

    清单1.一定要这么难吗?
    import java.util.regex.Matcher; import java.util.regex.Pattern; import junit.framework.TestCase; public class RegularExpressionTest extends TestCase { private String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private Pattern pattern; protected void setUp() throws Exception { this.pattern = Pattern.compile(this.zipRegEx); } public void testZipCode() throws Exception{ Matcher mtcher = this.pattern.matcher("22101"); boolean isValid = mtcher.matches(); assertTrue("Pattern did not validate zip code", isValid); } }

    许多人认为JUnit 4注释的使用受TestNG以及.NET的NUnit的影响。 请参阅相关主题 ,以了解更多关于在其他测试框架的注释。

    与新

    JUnit 4使用Java 5注释完全消除了这两种约定。 不再需要类层次结构,并且仅需使用新定义的@Test注释来修饰用作测试的方法。

    清单2显示了与清单1相同的测试,但使用批注进行了重新定义:

    清单2.使用注释进行测试
    import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertTrue; public class RegularExpressionTest { private static String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private static Pattern pattern; @BeforeClass public static void setUpBeforeClass() throws Exception { pattern = Pattern.compile(zipRegEx); } @Test public void verifyGoodZipCode() throws Exception{ Matcher mtcher = this.pattern.matcher("22101"); boolean isValid = mtcher.matches(); assertTrue("Pattern did not validate zip code", isValid); } }

    清单2中的测试可能并不容易编写,但是肯定更容易理解。

    文档简化

    注释的一个有用的副作用是,它们无需明确了解框架的内部模型,即可清楚地记录每种方法的意图。 有什么比用@Test装饰测试方法更清楚的呢? 这是对旧式JUnit的重大改进,即使您只想了解每种方法对整体测试用例的贡献,也需要对JUnit约定有相当的了解。

    注释在解析已经编写的测试时是一个很大的帮助,但是当您看到它们在编写测试过程中带来的额外好处时,注释会变得更加引人注目。

    使用注释进行测试

    Java 5注释使JUnit 4与以前的版本明显不同。 在本节中,我将使您熟悉在关键区域(例如,测试声明和异常测试)中使用批注,以及用于超时和忽略不需要或不可用的测试。

    测试声明

    在JUnit 4中声明测试是用@Test注释修饰测试方法的问题。 注意,您不需要从任何专门的类进行扩展,如清单3所示:

    清单3. JUnit 4中的测试声明
    import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertFalse; public class RegularExpressionTest { private static String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private static Pattern pattern; @BeforeClass public static void setUpBeforeClass() throws Exception { pattern = Pattern.compile(zipRegEx); } @Test public void verifyZipCodeNoMatch() throws Exception{ Matcher mtcher = this.pattern.matcher("2211"); boolean notValid = mtcher.matches(); assertFalse("Pattern did validate zip code", notValid); } }

    关于静态导入的说明

    我使用Java 5的静态导入功能来导入清单3中的Assert类的assertFalse()方法。这是因为测试类不像以前的JUnit版本那样从TestCase扩展而来。

    测试异常

    与早期版本的JUnit一样,通常最好指定测试抛出Exception 。 您唯一要忽略此规则的情况是,如果您正在尝试测试特定的异常。 如果测试抛出异常,则框架报告失败。

    如果您实际上想测试特定的异常,则JUnit 4的@Test批注支持expected参数,该参数旨在表示测试在执行时应抛出的异常类型。

    一个简单的比较说明了新参数带来的不同。

    JUnit 3.8中的异常测试

    清单4中的JUnit 3.8测试恰当地命名为testZipCodeGroupException() ,它验证试图获取我声明的第三组正则表达式将导致IndexOutOfBoundsException :

    清单4.在JUnit 3.8中测试异常
    import java.util.regex.Matcher; import java.util.regex.Pattern; import junit.framework.TestCase; public class RegularExpressionTest extends TestCase { private String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private Pattern pattern; protected void setUp() throws Exception { this.pattern = Pattern.compile(this.zipRegEx); } public void testZipCodeGroupException() throws Exception{ Matcher mtcher = this.pattern.matcher("22101-5051"); boolean isValid = mtcher.matches(); try{ mtcher.group(2); fail("No exception was thrown"); }catch(IndexOutOfBoundsException e){ } } }

    这个较旧的JUnit版本要求我为这种简单的测试做大量的编码-即编写一个try / catch并在未捕获到异常的情况下使测试失败。

    JUnit 4中的异常测试

    清单5中的异常测试与清单4中的异常测试没有什么不同,不同之处在于它使用了新的expected参数。 (请注意,通过将IndexOutOfBoundsException异常传递给@Test批注,我能够对清单4的测试进行改造。)

    清单5.使用“ expected”参数的异常测试
    import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.BeforeClass; import org.junit.Test; public class RegularExpressionJUnit4Test { private static String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private static Pattern pattern; @BeforeClass public static void setUpBeforeClass() throws Exception { pattern = Pattern.compile(zipRegEx); } @Test(expected=IndexOutOfBoundsException.class) public void verifyZipCodeGroupException() throws Exception{ Matcher mtcher = this.pattern.matcher("22101-5051"); boolean isValid = mtcher.matches(); mtcher.group(2); } }

    超时测试

    在JUnit 4中,测试用例可以将超时值作为参数。 如清单6所示, timeout值表示测试可以花费的最大运行时间:如果超过该时间,则测试将失败。

    清单6.使用超时值进行测试
    @Test(timeout=1) public void verifyFastZipCodeMatch() throws Exception{ Pattern pattern = Pattern.compile("^\\d{5}([\\-]\\d{4})?$"); Matcher mtcher = pattern.matcher("22011"); boolean isValid = mtcher.matches(); assertTrue("Pattern did not validate zip code", isValid); }

    使用超时进行测试很容易:只需用@Test装饰一个方法,后跟一个timeout值,就可以进行自动超时测试!

    忽略测试

    在JUnit 4之前,忽略残破或不完整的测试有些痛苦。 如果您希望框架忽略特定的测试,则必须更改其名称,以免遵循测试的命名法。 例如,我经常发现自己在测试方法之前放置了一个“ _”,以指示该测试不是在当前时刻进行的。

    JUnit 4引入了一个恰当地称为@Ignore的注释,该注释迫使框架忽略特定的测试方法。 您还可以传递一条消息,记录您对因忽略测试而发生的毫无戒心的开发人员的决定。

    @Ignore批注

    清单7显示了忽略正则表达式尚不起作用的测试是多么容易:

    清单7.忽略此测试
    @Ignore("this regular expression isn't working yet") @Test public void verifyZipCodeMatch() throws Exception{ Pattern pattern = Pattern.compile("^\\d{5}([\\-]\\d{4})"); Matcher mtcher = pattern.matcher("22011"); boolean isValid = mtcher.matches(); assertTrue("Pattern did not validate zip code", isValid); }

    记录在案

    尝试在Eclipse中运行此测试(例如)将报告忽略的测试,如图1所示:

    图1. Eclipse中如何显示被忽略的测试

    测试治具

    测试夹具不是JUnit 4的新增功能,但是夹具模型是新增和改进的。 在本节中,我解释了为什么以及在何处需要使用固定装置,然后向您展示了旧的固定装置与JUnit 4闪亮的新模型之间的区别。

    为什么要使用灯具?

    夹具通过合同来保证重用,以确保在测试之前或之后都运行特定的逻辑。 在较旧的JUnit版本中,无论您是否实现了固定装置,该协定都是隐式的。 但是,JUnit 4通过注解使灯具显式化,这意味着仅在您实际决定使用灯具时才执行合同。

    通过确保在测试之前或之后均可运行灯具的合同,您可以编写可重复使用的逻辑代码。 例如,此逻辑可能正在初始化您将在多个测试用例中测试的类,或者甚至是在运行依赖数据的测试之前填充数据库的逻辑。 无论哪种方式,使用固定装置都可以确保更易于管理的测试用例:一种依赖于通用逻辑的测试用例。

    当您运行许多使用相同逻辑的测试并且其中一些或全部失败时,夹具特别有用。 您无需在每个测试的设置逻辑中进行筛选,而是可以在一个地方查看来推断失败的原因。 此外,如果某些测试通过而另一些测试失败,则您可能可以避免将夹具逻辑完全视为失败的根源。

    固定装置

    较旧的JUnit版本采用了一种不太灵活的夹具模型,在该模型中,您必须通过setUp()和tearDown()方法包装所有测试方法。 您可以在清单8中看到该模型的潜在缺点,其中实现了setUp()方法,因此将运行两次-对于定义的每个测试一次:

    清单8.固定装置
    import java.util.regex.Matcher; import java.util.regex.Pattern; import junit.framework.TestCase; public class RegularExpressionTest extends TestCase { private String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private Pattern pattern; protected void setUp() throws Exception { this.pattern = Pattern.compile(this.zipRegEx); } public void testZipCodeGroup() throws Exception{ Matcher mtcher = this.pattern.matcher("22101-5051"); boolean isValid = mtcher.matches(); assertEquals("group(1) didn't equal -5051", "-5051", mtcher.group(1)); } public void testZipCodeGroupException() throws Exception{ Matcher mtcher = this.pattern.matcher("22101-5051"); boolean isValid = mtcher.matches(); try{ mtcher.group(2); fail("No exception was thrown"); }catch(IndexOutOfBoundsException e){ } } }

    解决它

    在早期版本的JUnit中,可以使用TestSetup装饰器指定一个夹具只运行一次,但这是一个繁琐的操作,如清单9所示(注意必需的suite()方法):

    清单9. JUnit 4之前的TestSetup
    import java.util.regex.Matcher; import java.util.regex.Pattern; import junit.extensions.TestSetup; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import junit.textui.TestRunner; public class OneTimeRegularExpressionTest extends TestCase { private static String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private static Pattern pattern; public static Test suite() { TestSetup setup = new TestSetup( new TestSuite(OneTimeRegularExpressionTest.class)) { protected void setUp() throws Exception { pattern = Pattern.compile(zipRegEx); } }; return setup; } public void testZipCodeGroup() throws Exception { Matcher mtcher = pattern.matcher("22101-5051"); boolean isValid = mtcher.matches(); assertEquals("group(1) didn't equal -5051", "-5051", mtcher.group(1)); } public void testZipCodeGroupException() throws Exception { Matcher mtcher = pattern.matcher("22101-5051"); boolean isValid = mtcher.matches(); try { mtcher.group(2); fail("No exception was thrown"); } catch (IndexOutOfBoundsException e) { } } }

    可以说,在JUnit 4之前,解决固定装置的麻烦几乎比其应有的麻烦多。

    4.0的灵活性

    JUnit 4使用注释减少了许多固定装置的开销,从而使您可以为每个测试运行固定装置,或者为整个类仅运行一次固定装置,或者根本不运行。 夹具注释有四个:两个用于类级夹具,两个用于方法级夹具。 在类级别,您具有@BeforeClass和@AfterClass ,在方法(或测试)级别,您具有@Before和@After 。

    清单10中的测试用例包括一个使用@Before批注针对两个测试运行的固定装置:

    清单10.使用注释的灵活的灯具
    import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; public class RegularExpressionJUnit4Test { private static String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private static Pattern pattern; @Before public static void setUpBeforeClass() throws Exception { pattern = Pattern.compile(zipRegEx); } @Test public void verifyZipCodeNoMatch() throws Exception{ Matcher mtcher = this.pattern.matcher("2211"); boolean notValid = mtcher.matches(); assertFalse("Pattern did validate zip code", notValid); } @Test(expected=IndexOutOfBoundsException.class) public void verifyZipCodeGroupException() throws Exception{ Matcher mtcher = this.pattern.matcher("22101-5051"); boolean isValid = mtcher.matches(); mtcher.group(2); } }

    一次性治具

    如果您只想运行一个灯具怎么办? 与其实现清单9所示的老式装饰器,不如使用清单11所示的@BeforeClass批注:

    清单11. JUnit 4中的一次性设置
    import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; public class RegularExpressionJUnit4Test { private static String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private static Pattern pattern; @BeforeClass public static void setUpBeforeClass() throws Exception { pattern = Pattern.compile(zipRegEx); } @Test public void verifyZipCodeNoMatch() throws Exception{ Matcher mtcher = this.pattern.matcher("2211"); boolean notValid = mtcher.matches(); assertFalse("Pattern did validate zip code", notValid); } @Test(expected=IndexOutOfBoundsException.class) public void verifyZipCodeGroupException() throws Exception{ Matcher mtcher = this.pattern.matcher("22101-5051"); boolean isValid = mtcher.matches(); mtcher.group(2); } }

    撕下

    如果您想知道,旧的tearDown()功能在新的夹具模型下并没有消失。 如果要执行tearDown() ,则可以简单地创建一个新方法并根据需要使用@After或@AfterClass 。

    灵活性平方

    您可以在JUnit 4中为一个测试用例指定多个夹具。新的注释驱动夹具无法阻止您创建多个@BeforeClass夹具方法。 但是请记住,从当前版本的JUnit 4开始,您无法指定要首先运行哪些灯具方法,如果您决定使用多个灯具方法,可能会变得棘手。

    运行它:在JUnit 4中测试

    新的和改进的JUnit 4最引人注目的功能之一就是缺少套件,该套件用于对测试进行逻辑分组并将其作为一个单元运行。 在本部分中,我将介绍新的,简化的注释,这些注释已替换了套件,并向您展示了如何在Eclipse和Ant中运行JUnit 4测试。

    老式套房

    因此,您可以看到其中的区别,请查看清单12中所示的旧式JUnit套件(该套件将两个逻辑测试类分组并作为一个单元运行它们):

    清单12.一个老式的JUnit套件
    import junit.framework.Test; import junit.framework.TestSuite; public class JUnit3Suite { public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(OneTimeRegularExpressionTest.suite()); suite.addTestSuite(RegularExpressionTest.class); return suite; } }

    两个甜美的新注释

    在JUnit 4中,套件语义已替换为两个新的注释。 第一个@RunWith旨在帮助让不同的运行程序(框架中内置的运行程序除外)执行特定的测试类。 JUnit 4捆绑了一个套件运行程序,名为Suite ,您必须在@RunWith批注中指定@RunWith 。 此外,您必须提供另一个名为@SuiteClasses注释,该注释将旨在表示测试套件的类的列表作为参数。

    清单13.这些注释非常不错
    import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses({ParametricRegularExpressionTest.class, RegularExpressionTest.class, TimedRegularExpressionTest.class}) public class JUnit4Suite { }

    如果新的JUnit 4批注对您来说很奇怪,请不用担心。 显然,JUnit 4的创建者有类似的感觉。 他们在Javadocs中解释说,他们期望Runner API会“随着我们学习人们如何真正使用它而改变”。 至少他们是诚实的!

    在Eclipse中运行JUnit 4测试

    您可以选择通过Eclipse之类的IDE或通过命令行运行JUnit 4测试类。 您可以通过选择Run As JUnit测试选项在Eclipse 3.2及更高版本中运行JUnit测试。 通过命令行运行测试需要执行org.junit.runner.JUnitCore类,并将测试的标准名称作为参数传递。

    例如,在Eclipse中,如果您不想使用捆绑的JUnit运行器,则可以定义一个新的运行配置,并首先指定JUnitCore类,如图2所示:

    图2.在Eclipse中运行JUnit 4命令行测试的第一步

    指定测试

    接下来,您需要通过将测试的完全限定名称添加到“参数”选项卡的“程序参数”文本框中来指定要运行的测试,如图3所示:

    图3.在Eclipse中运行JUnit命令行测试的第二步

    Ant和JUnit 4

    目前,Ant和JUnit一直是一支很棒的团队,许多开发人员预计,只有引入JUnit 4才能使这种关系变得更好。事实证明,这确实很困难。 如果您正在运行1.7之前的任何版本的Ant,则不能简单地开箱即用地运行JUnit 4测试。 这并不是说您无法运行测试-只是您不能开箱即用地运行它们。

    不合适的配对

    在Ant(1.7版之前)中运行JUnit 4测试(在清单14中)会产生一些有趣的结果:

    清单14.一个简单的JUnit 4测试类
    import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertTrue; public class RegularExpressionTest { private static String zipRegEx = "^\\d{5}([\\-]\\d{4})?$"; private static Pattern pattern; @BeforeClass public static void setUpBeforeClass() throws Exception { pattern = Pattern.compile(zipRegEx); } @Test public void verifyGoodZipCode() throws Exception{ Matcher mtcher = this.pattern.matcher("22101"); boolean isValid = mtcher.matches(); assertTrue("Pattern did not validate zip code", isValid); } }

    多次失败

    在Ant中使用古老的junit任务会产生清单15中的错误:

    清单15.一堆错误
    [junit] Running test.com.acme.RegularExpressionTest [junit] Tests run: 1, Failures: 1, Errors: 0, Time elapsed: 0.047 sec [junit] Testsuite: test.com.acme.RegularExpressionTest [junit] Tests run: 1, Failures: 1, Errors: 0, Time elapsed: 0.047 sec [junit] Testcase: warning took 0.016 sec [junit] FAILED [junit] No tests found in test.com.acme.RegularExpressionTest [junit] junit.framework.AssertionFailedError: No tests found in test.com.acme.RegularExpressionTest [junit] Test test.com.acme.RegularExpressionTest FAILED

    复古的解决方案

    如果要在1.7之前的Ant版本上运行JUnit 4测试,则必须使用suite()方法对测试用例进行改造,该方法返回JUnit4TestAdapter的实例,如清单16所示:

    清单16.旧方法的新用法
    public static junit.framework.Test suite(){ return new JUnit4TestAdapter(RegularExpressionTest.class); }

    由于类似的@Test批注,因此您必须在这种情况下完全限定Test的返回类型。 一旦suite()方法到位,任何版本的Ant都会愉快地运行JUnit 4测试!

    参数测试

    每隔一段时间,应用程序的业务逻辑就要求您编写大量变化的测试以确保其正常运行。 在以前的JUnit版本中,这种情况可能非常不方便,主要是因为将参数组更改为被测方法意味着要为每个唯一组编写一个测试用例。

    JUnit 4引入了一项出色的新功能,可让您创建可以由参数值提供的通用测试。 因此,您可以创建一个测试用例并多次运行-对您创建的每个参数一次。

    参数简单

    在JUnit 4中创建参数测试仅需五个步骤:

    创建一个不带参数的通用测试。 创建一个static feeder方法,该方法返回Collection类型并使用@Parameter批注对其进行@Parameter 。 为步骤1中定义的通用方法中所需的参数类型创建类成员。 创建一个采用这些参数类型的构造函数,并将它们对应地链接到步骤3中定义的类成员。 通过@RunWith注释指定要与Parameterized类一起运行的@RunWith 。

    我将一步一步地完成这些步骤。

    步骤1.创建一个通用测试

    清单17显示了一个通用测试,用于根据正则表达式验证各种值。 请注意,未定义phrase和match值。

    清单17.通用测试
    @Test public void verifyGoodZipCode() throws Exception{ Matcher mtcher = this.pattern.matcher(phrase); boolean isValid = mtcher.matches(); assertEquals("Pattern did not validate zip code", isValid, match); }

    第2步。创建供料器方法

    下一步是创建一个feeder方法,您必须将其声明为static并返回Collection类型。 您需要使用@Parameters注释装饰该方法。 在该方法内部,您只需创建一个多维Object数组并将其转换为List ,如清单18所示:

    清单18.带有@Parameters批注的feeder方法
    @Parameters public static Collection regExValues() { return Arrays.asList(new Object[][] { {"22101", true }, {"221x1", false }, {"22101-5150", true }, {"221015150", false }}); }

    步骤3.创建两个班级成员

    因为参数的类型为String和boolean ,所以下一步是创建两个类成员:

    清单19.声明两个类成员
    private String phrase; private boolean match;

    步骤4.创建一个构造函数

    接下来创建的构造函数将类成员链接到您的参数值,如清单20所示:

    清单20.匹配值的构造函数
    public ParametricRegularExpressionTest(String phrase, boolean match) { this.phrase = phrase; this.match = match; }

    步骤5.指定Parameterized类

    最后,在类级别上指定必须使用Parameterized类运行此测试,如清单21所示:

    清单21.指定Parameterized和@RunWith批注
    @RunWith(Parameterized.class) public class ParametricRegularExpressionTest { //... }

    运行测试

    当执行测试类时,通用的verifyGoodZipCode()测试方法运行四次,对于清单18中regExValues()数据馈送器方法中定义的每个值对一次。

    例如,如果您在Eclipse中运行此测试,它将报告四次测试运行,如图4所示:

    图4.在Eclipse中运行的参数测试

    还有什么是新的?

    除了到目前为止讨论的重要更改之外,JUnit 4还引入了一些较小的更改。 即增加了一个新的断言方法和消除了终端状态。

    一个新的断言

    JUnit 4添加了新的assert方法来比较数组内容。 这不是一个大的补充,但这确实意味着您无需再遍历数组的内容并声明每个单独的项目。

    例如,清单22中的代码在旧版本的JUnit中是不可能的。 该测试用例失败,因为每个数组的第二个元素略有不同。

    清单22. assertEquals现在在JUnit 4中支持数组
    @Test public void verifyArrayContents() throws Exception{ String[] actual = new String[] {"JUnit 3.8.x", "JUnit 4", "TestNG"}; String[] var = new String[] {"JUnit 3.8.x", "JUnit 4.1", "TestNG 5.5"}; assertEquals("the two arrays should not be equal", actual, var); }

    没有更多的错误!

    JUnit 4中的一个小但可喜的变化是它消除了错误的概念。 以前的版本会报告失败次数和错误次数,而在JUnit 4中,测试要么通过要么失败。

    有趣的是,虽然消除了一个状态,但又添加了一个新状态,这是因为可以忽略测试。 当执行一系列测试时,JUnit 4会报告运行的测试数量,失败的数量以及被忽略的测试数量。

    Wrapping up

    JUnit 4完全不同于其原始设计,并不意味着该框架的运作方式有所不同-原始框架的强大功能和简单性是完整的。 实际上,当您深入研究框架时,您应该发现它没有牺牲任何引发开发人员测试革命的核心原则,尽管它添加了一些引人注目的新功能。

    在本教程中,您遍历了了解JUnit 4的过程,从测试声明到参数测试。 您发现了定时测试和异常测试等新功能,并了解了对固定功能和逻辑分组等熟悉功能的更改。 您还看到了测试运行在Eclipse中的外观,并了解了一个简单的解决方法,该方法可让您在任何版本的Ant(甚至是1.7之前的版本)中运行测试。

    如果希望从本教程中学到任何东西,那就是注释不会使JUnit失去吸引力,它们确实增加了相当的易用性。 尝试一下批注:他们会让您不知不觉中跳入测试写作!


    翻译自: https://www.ibm.com/developerworks/java/tutorials/j-junit4/index.html

    相关资源:微信小程序源码-合集6.rar
    Processed: 0.043, SQL: 10