JUnit(四)高级之规则_MD
来源:互联网 发布:淘宝商城铂金会员 编辑:程序博客网 时间:2024/06/08 15:10
Rules[规则]
规则允许在测试类中非常灵活的增加或重新定义每个测试方法的行为。测试人员可以重用或拓展下面提供的规则或编写自己的规则。
我们在使用规则的时候需要使用@Rule
注解进行注释,被该注解注释的类需要是TestRule
接口的实现。
TestRule接口的实现:
ErrorCollector
: collect multiple errors in one test methodExpectedException
: make flexible assertions about thrown exceptionsExternalResource
: start and stop a server, for exampleTemporaryFolder
: create fresh files, and delete after testTestName
: remember the test name for use during the methodTestWatcher
: add logic at events during method executionTimeout
: cause test to fail after a set timeVerifier
: fail test if object state ends up incorrect
一、基础规则
1.1 TemporaryFolder[临时文件夹] Rule
TemporaryFolder
规则允许创建文件或文件夹,在测试方法(无论是通过还是失败)执行完成时会被删除。默认情况下,如果资源无法被删除是不会抛出异常的:
public static class HasTempFolder { @Rule public final TemporaryFolder folder = new TemporaryFolder(); @Test public void testUsingTempFolder() throws IOException { File createdFile = folder.newFile("myfile.txt"); File createdFolder = folder.newFolder("subfolder"); // ... }}
TemporaryFolder#newFolder(String... folderNames)
会递归的创建一个临时文件夹。TemporaryFolder#newFile()
创建一个随机名称的文件, 同样#newFolder()
创建一个随机名称的文件夹- 从 4.13 版本 开始,
TemporaryFolder
optionally allows strict verification of deleted resources which fails the test withAssertionError
if resources cannot be deleted. 此功能只能选择用#builder()
方法。默认情况下禁用严格验证[strict verification],保持向后兼容性[backward compatibility]。
@Rulepublic TemporaryFolder folder = TemporaryFolder.builder().assureDeletion().build();//构建器模式
1.2 ExternalResource[外部资源] Rules
ExternalResource
是规则(例如TemporaryFolder)的基础类,在测试之前建立一个外部资源(一个文件,套接字[socket],服务[server],数据库连接,等等),并且保证tear it down afterward。
public static class UsesExternalResource { Server myServer = new Server(); @Rule public final ExternalResource resource = new ExternalResource() { @Override protected void before() throws Throwable { myServer.connect(); }; @Override protected void after() { myServer.disconnect(); }; }; @Test public void testFoo() { new Client().run(myServer); }}
1.3 ErrorCollector Rule
ErrorCollector
规则允许在第一个问题发现之后继续运行(例如,收集下面不正确的行到一个表中,然后一次性报告所有错误。)
public static class UsesErrorCollectorTwice { @Rule public final ErrorCollector collector = new ErrorCollector(); @Test public void example() { collector.addError(new Throwable("first thing went wrong")); collector.addError(new Throwable("second thing went wrong")); }}
1.4 Verifier Rule
Verifier
是规则(例如ErrorCollector)的一个基类, which can turn otherwise passing test methods into failing tests if a verification check is failed.[无论测试的执行情况是什么,只要验证框架不通过,则视为测试失败。]
public static class ErrorLogVerifier { private ErrorLog errorLog = new ErrorLog(); @Rule public Verifier verifier = new Verifier() { @Override public void verify() { assertTrue(errorLog.isEmpty()); } } @Test public void testThatMightWriteErrorLog() { // ... }}
注意:自己测试验证发现,在测试方法执行完成后会执行以下Verifier的verify方法。
1.5 TestWatchman/TestWatcher Rules
TestWatchman 是JUnit 4.7引入的,但是已经过时,被 TestWatcher [4.9引入] 所取代。
TestWatcher (and the deprecated TestWatchman) are base classes for Rules that take note of the testing action, without modifying it. For example, this class will keep a log of each passing and failing test:
TestWatcher
是一个规则的基础类,that take note of the testing action,而不用修改测试类。例如,这个类将保存一个日志在一个通过以及失败的测试:
import static org.junit.Assert.fail;import org.junit.AssumptionViolatedException;import org.junit.Rule;import org.junit.Test;import org.junit.rules.TestRule;import org.junit.rules.TestWatcher;import org.junit.runner.Description;import org.junit.runners.model.Statement;public class WatchmanTest { private static String watchedLog; @Rule public final TestRule watchman = new TestWatcher() { @Override public Statement apply(Statement base, Description description) { return super.apply(base, description); } @Override protected void succeeded(Description description) { watchedLog += description.getDisplayName() + " " + "success!\n"; } @Override protected void failed(Throwable e, Description description) { watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n"; } @Override protected void skipped(AssumptionViolatedException e, Description description) { watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n"; } @Override protected void starting(Description description) { super.starting(description); } @Override protected void finished(Description description) { super.finished(description); } }; @Test public void fails() { fail(); } @Test public void succeeds() { }}
1.6 TestName Rule
TestName
规则使得当前测试的名字在测试内部是可利用的:
public class NameRuleTest { @Rule public final TestName name = new TestName(); @Test public void testA() { assertEquals("testA", name.getMethodName()); } @Test public void testB() { assertEquals("testB", name.getMethodName()); }}
1.7 Timeout Rule
Timeout规则将同样的时间应用到每一个类。
public static class HasGlobalTimeout { public static String log; @Rule public final TestRule globalTimeout = Timeout.millis(20); @Test public void testInfiniteLoop1() { log += "ran1"; for(;;) {} } @Test public void testInfiniteLoop2() { log += "ran2"; for(;;) {} }}
1.8 ExpectedException Rules
The ExpectedException
Rule allows in-test specification of expected exception types and messages:
public static class HasExpectedException { @Rule public final ExpectedException thrown = ExpectedException.none(); @Test public void throwsNothing() { } @Test public void throwsNullPointerException() { thrown.expect(NullPointerException.class); throw new NullPointerException(); } @Test public void throwsNullPointerExceptionWithMessage() { thrown.expect(NullPointerException.class); thrown.expectMessage("happened?"); thrown.expectMessage(startsWith("What")); throw new NullPointerException("What happened?"); }}
二、高级
@ClassRule
The ClassRule
annotation extends the idea of method-level Rules, adding static fields that can affect the operation of a whole class. Any subclass of ParentRunner
, including the standard BlockJUnit4ClassRunner
and Suite
classes, will support ClassRules
.
For example, here is a test suite that connects to a server once before all the test classes run, and disconnects after they are finished:
@RunWith(Suite.class)@SuiteClasses({A.class, B.class, C.class})public class UsesExternalResource { public static final Server myServer = new Server(); @ClassRule public static final ExternalResource resource = new ExternalResource() { @Override protected void before() throws Throwable { myServer.connect(); }; @Override protected void after() { myServer.disconnect(); }; };}
RuleChain
The RuleChain rule allows ordering of TestRules:
public static class UseRuleChain { @Rule public final TestRule chain = RuleChain .outerRule(new LoggingRule("outer rule")) .around(new LoggingRule("middle rule")) .around(new LoggingRule("inner rule")); @Test public void example() { assertTrue(true); }}
writes the log
starting outer rulestarting middle rulestarting inner rulefinished inner rulefinished middle rulefinished outer rule
Custom Rules
Most custom rules can be implemented as an extension of the ExternalResource
rule. However, if you need more information about the test class or method in question, you’ll need to implement the TestRule
interface.
import org.junit.rules.TestRule;import org.junit.runner.Description;import org.junit.runners.model.Statement;public class IdentityRule implements TestRule { @Override public Statement apply(final Statement base, final Description description) { return base; }}
Of course, the power from implementing TestRule
comes from using a combination of custom constructors, adding methods to the class for use in tests, and wrapping the provided Statement
in a new Statement
. For instance, consider the following test rule that provides a named logger for every test:
package org.example.junit;import java.util.logging.Logger;import org.junit.rules.TestRule;import org.junit.runner.Description;import org.junit.runners.model.Statement;public class TestLogger implements TestRule { private Logger logger; public Logger getLogger() { return this.logger; } @Override public Statement apply(final Statement base, final Description description) { return new Statement() { @Override public void evaluate() throws Throwable { logger = Logger.getLogger(description.getTestClass().getName() + '.' + description.getDisplayName()); base.evaluate(); } }; }}
Then that rule could be applied like so:
import java.util.logging.Logger;import org.example.junit.TestLogger;import org.junit.Rule;import org.junit.Test;public class MyLoggerTest { @Rule public final TestLogger logger = new TestLogger(); @Test public void checkOutMyLogger() { final Logger log = logger.getLogger(); log.warn("Your test is showing!"); }}
- JUnit(四)高级之规则_MD
- JUnit(二)高级之运行器_MD
- JUnit(一)基础_MD
- PMD规则之Junit Rules
- 编写代码之原则总结_MD
- JUnit(三)高级之Matchers and assertThat_MD
- Junit高级
- Junit使用之四---使用Junit测试WEB项目
- 权限组件之四(规则)
- 权限组件之四(规则)
- junit(四)
- Junit 测试的规则
- 羊群效应:搜索引擎暗规则之四
- 学习XML之四:XML 语法规则
- ant junit 高级使用
- Java高级JUnit、注解
- Junit 使用--高级篇
- Junit学习笔记之四:dbunit和easymock
- Noip 2011 计算系数
- Retrofit上传文件
- MySQL5.7.20安装过程 和常用指令
- MySQL
- (转)智能投顾这么干才靠谱!BondIT获复星B轮投资
- JUnit(四)高级之规则_MD
- 纸带 线段树+离散化
- 深度学习在SLAM中的应用
- 畅通工程之局部最小花费问题 (并查集)
- ARP协议数据报
- 多表查询之子查询,in,any,all,exists,
- 详解DNS的常用记录(下):DNS系列之三
- uva11090 给你一个有向图,求出平均权值最小的环
- ScrollView中EditText导致自动滚动问题