参加敏捷培训时,教练提到Junit4的Runner和Rule,于是特上网查一下,发现很多都讲的太理论,或者是举的例子实在是太牵强。多搜索了几下,搜索到两篇我觉得写的非常好的文章。
文章地址:http://www.blogjava.net/jiangshachina/archive/2011/12/14/366289.html
在使用JUnit的过程中,大家可能会对JUnit进行一些扩展。本文中的示例为JUnit4定义了一个新的Annotation,并相应地对已有的Runner进行扩展,使其能够解析新引入的Annotation。
本文臆造了一个示例,会在执行单元测试方法之前,自动地为单元测试方法打印日志。该示例会为JUnit定义一个新的Annotation用于指定要打印的日志内容,并对JUnit默认提供的Runner实现BlockJUnit4ClassRunner进行扩展,使其能够识别这个新的Annotation。
1. 定义Annotation
TestLogger是一个作用于方法的Annotation,它只有一个属性,用于指定日志的内容,其代码如下所示:
@Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface TestLogger { public String log() default ""; }
2. 扩展Runner
JUnit提供了若干个Runner的实现,如BlockJUnit4ClassRunner,Suite,其中BlockJUnit4ClassRunner用来执行单个测试用例类。LoggedRunner将扩展BlockJUnit4ClassRunner,覆写其中的methodBlock()方法。新的methodBlock()方法会在一开始试图获取被执行测试方法中的TestLogger Annotation,如果存在的话,就会打印出指定的日志,每行日志以当时的执行时间与完整方法名作为前缀。该类的代码如下所示:
public class LoggedRunner extends BlockJUnit4ClassRunner { private static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss_SSS"); public LoggedRunner(Class<?> klass) throws InitializationError { super(klass); } @Override protected Statement methodBlock(FrameworkMethod method) { Method classMethod = method.getMethod(); TestLogger loggerAnnotation = classMethod.getAnnotation(TestLogger.class); if (loggerAnnotation != null) { StringBuilder log = new StringBuilder(format.format(new Date())); log.append(" ").append(classMethod.getDeclaringClass().getName()) .append("#").append(classMethod.getName()).append(": ") .append(loggerAnnotation.log()); System.out.println(log.toString()); } return super.methodBlock(method); } }
3. 应用程序
Calculator是一个简单的应用程序,其中定义了一个除法方法,代码如下所示:
public class Calculator { public int divide(int a, int b) { return a / b; } }
4. 单元测试程序
CalculatorTest是一个简单的单元测试程序,它会使用两种方式对Calculator中的divide()方法进行单元测试。其代码如下所示:
@RunWith(LoggedRunner.class) public class CalculatorTest { private static Calculator calculator = null; @BeforeClass public static void createCalculator() { calculator = new Calculator(); } @Test @TestLogger(log = "a simple division.") public void simpleDivide() { int value = calculator.divide(8, 2); Assert.assertTrue(value == 4); } @Test(expected = ArithmeticException.class) @TestLogger(log = "divided by zero, and an ArithmeticException thrown.") public void dividedByZero() { calculator.divide(8, 0); } }
值得注意的是,CalculatorTest特别指定LoggedRunner作为测试执行器(@RunWith(LoggedRunner.class));同时,每个单元测试方法,simpleDivide()与dividedByZero(),都使用了Annotation TestLogger,为其指定日志内容。当执行上述单元测试时,会自动地打印出如下形式的日志内容:
2014-09-23_23:02:33_890 com.bijian.study.CalculatorTest#simpleDivide: a simple division 2014-09-23_23:02:33_890 com.bijian.study.CalculatorTest#dividedByZero: divided by zero, and an ArithmeticException thrown.
5. 小结
通过对BlockJUnit4ClassRunner的扩展,可以让JUnit在运行测试用例时做一些额外的工作。但这种直接修改默认Test Runner的方式并不被提倡,可使用Test Rule来达到相同的扩展目的。
相关推荐
1. **自定义 JUnit 运行器支持**:允许开发人员创建自己的 JUnit 运行器类,这些类可以扩展 `org.junit.runner.Runner` 或其子类,如 `org.junit.platform.runner.JUnitPlatformRunner`。这样,开发者可以在 Eclipse...
《Junit4 入门详解》 JUnit 是一个用于Java编程语言的单元测试框架,而Junit4作为其第四代版本,引入了许多新特性和改进,使得测试...同时,不断探索Junit4的高级特性,你会发现它能为你的软件开发带来无尽的便利。
《深入解析JUnit4:探索开源测试框架的精髓》 JUnit4是Java开发中广泛使用的单元测试框架,它的开源性质使得开发者能够深入理解其内部机制,从而更好地利用它进行测试驱动开发(TDD)。本篇文章将从`junit4-example...
#### 四、深入探索JUnit - **测试套件的构建**:可以使用`TestSuite`类来组织多个测试用例为一个整体,方便批量执行。 - **自定义测试运行器**:通过实现`TestRunner`接口,可以创建自定义的测试运行器,实现更灵活...
《Junit 深入探索:源码剖析与测试工具运用》 Junit,作为Java领域最常用的单元测试框架,是每一个开发者必备的技能之一。本文将深入探讨Junit的内在机制,通过源码分析以及实际应用示例,帮助读者更全面地理解和...
4. **断言**:在测试方法中,使用JUnit提供的`assertXXX`方法进行断言,确保预期的结果与实际结果相符。同时,也可以使用Mockito等库来模拟协作对象的行为,进一步控制测试的边界条件。 5. **异常测试**:对于那些...
《less4j-1.8.3.zip与junit-karma-testrunner.zip:JavaScript测试与开源项目的探索》 在IT领域,开源项目以其开放、共享的精神推动着技术的发展,为开发者提供了丰富的工具和资源。本篇文章将围绕两个开源项目展开...
总的来说,JUnit 4 Extensions如JUnitExt是单元测试领域的宝贵工具,它们通过扩展JUnit的功能,帮助开发人员编写更高效、更灵活的测试代码,提高了软件质量保证的效率。对于那些需要对测试进行更精细控制的项目,...
通过Java Test Runner扩展,您可以方便地运行JUnit或TestNG测试,并查看测试结果。 11. **插件市场探索** 除了上述基础配置,VSCode的插件市场有大量针对Java开发的扩展,如代码质量检查工具SonarLint,Java文档...
- `Java Test Runner`:支持运行和调试JUnit测试。 4. **配置VSCode工作区** 创建一个新的VSCode工作区,或者打开已有的Java项目。在工作区根目录下创建一个名为`.vscode`的文件夹,然后在这个文件夹里创建一个`...
6. **Spring测试**:Spring提供测试支持,包括`@RunWith(SpringJUnit4ClassRunner.class)`和`@ContextConfiguration`等注解,帮助我们在MyEclipse中编写单元测试和集成测试,确保代码质量。 7. **Maven或Gradle构建...
此外,Spring 3.2还加强了测试支持,包括MockMVC用于模拟Spring MVC请求,以及`@RunWith(SpringJUnit4ClassRunner.class)`注解配合`@ContextConfiguration`进行Spring应用上下文的加载,使单元测试和集成测试变得...
Spring提供了丰富的测试支持,包括`SpringJUnit4ClassRunner`和`Mockito`的集成,使得开发者可以方便地进行单元测试和集成测试。源代码中的测试类为我们展示了如何使用这些工具进行测试驱动开发。 7. **模块化设计...
Spring Test模块提供了丰富的单元测试和集成测试工具,如`@RunWith(SpringJUnit4ClassRunner.class)`、`@ContextConfiguration`等,可以帮助开发者编写整洁且隔离的测试代码。 总结,Spring Framework 3.2.x是一个...
【Java基础教程】IDEA的使用与多线程——IDEA的介绍 在学习和开发Java应用程序时,选择一个高效且功能丰富的集成开发环境(IDE)至关...在实际开发中,不断探索和利用IDEA的各种特性,将使你的编程生涯更加得心应手。
import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions(features = "src/test/resources/features", glue = {"com.example.steps"}) public class RunCucumberTest { // 空类,仅用于...
它包括了JUnit和TestNG的扩展,使得测试Spring应用变得简单且高效。Spring Test允许开发者直接在测试类中注入Spring容器中的bean,无需复杂的配置,大大简化了测试过程。 二、Spring Test的核心组件 1. `@RunWith...
4. **运行测试**:Cucumber可以自动生成一个运行器类(Runner class),通过这个类来执行.feature文件中的测试场景。使用`@CucumberOptions`注解配置运行参数,如指定特征文件位置、格式化输出等。 5. **断言和数据...