Rules

我们之前处理异常的时候用到过Rules,当然还有很多其他规则。Rules允许弹性的添加或者重定义测试方法的行为。测试者可以重复使用或者扩展下面的某一个Rules,也可以写一个属于自己的规则。

这里先展示一张 TestRule的类图:

基本的规则有:

1.TemporaryFolder Rule

  • 该规则建立的文件或者文件夹会在测试方法结束之后自动删除(不管测试pass还是fail)。默认情况下,即使资源删不掉也不会抛出异常。

[java] view plaincopy

  1. import java.io.File;
  2. import java.io.IOException;
  3. import org.junit.Rule;
  4. import org.junit.Test;
  5. import org.junit.rules.TemporaryFolder;
  6. public class RuleTest {
  7. @Rule
  8. public TemporaryFolder folder=new TemporaryFolder();
  9. @Test
  10. public void test() throws IOException {
  11. File aFile=folder.newFile("myfile.txt");
  12. File aFolder=folder.newFolder("subfolder");
  13. }
  14. }
  • TemporaryFolder#newFolder(String...folderNames) 会递归深入的新建多个文件夹。
  • TemporaryFolder#newFile() 会新建一个带有随机名字的文件,#newFolder() 会新建一个带有随机名字的文件夹。
  • 从 4.13开始,如果测试结束之后资源不能被删除, TemporaryFolder 可以选择允许测试以 AssertionError的方式fail。但是这个特性只有在使用 #builder()的方法才可以被激活。为了向后兼容默认情况下还是不会抛出异常。

@Rule
public TemporaryFolder folder=TemporaryFolder.builder().assureDeletion().build();

2.ExternalResource Rules

  • ExternalResource用来对外部资源进行管理,包括在测试之前进行外部资源准备,测试之后对测试资源进行回收等工作。在创建测试文件、连接服务器、准备数据库连接等情况下用的比较多。

[java] view plaincopy

  1. import org.junit.Rule;
  2. import org.junit.Test;
  3. import org.junit.rules.ExternalResource;
  4. public class RuleTest2 {
  5. @Rule
  6. public ExternalResource external = new ExternalResource()
  7. {
  8. protected void before() throws Throwable
  9. {
  10. System.out.println("Perparing test data.");
  11. System.out.println("Test data is Ready!");
  12. }
  13. protected void after()
  14. {
  15. System.out.println("Cleaning test data.");
  16. }
  17. };
  18. @Test
  19. public void test1()
  20. {
  21. System.out.println("Test 1 executing...");
  22. }
  23. @Test
  24. public void test2()
  25. {
  26. System.out.println("Test 2 executing...");
  27. }
  28. @Test
  29. public void test3()
  30. {
  31. System.out.println("Test 3 executing...");
  32. }
  33. }

运行结果:

Perparing test data.
Test data is Ready!
Test 1 executing...
Cleaning test data.
Perparing test data.
Test data is Ready!
Test 2 executing...
Cleaning test data.
Perparing test data.
Test data is Ready!
Test 3 executing...
Cleaning test data.

3. ErrorCollector Rule

  • 继承自下面的Verifier Rule。ErrorCollector
    规则允许测试在第一个问题出现的时候继续执行,然后执行完之后一次性汇报结果。比如说测试一个表格里的所有的行,在第一行发现错误之后继续执行,直到所有
    的错误都发现才停止,然后一次性汇报所有的结果。

[java] view plaincopy

  1. import org.junit.Rule;
  2. import org.junit.Test;
  3. import org.junit.rules.ErrorCollector;
  4. public class TestRule3 {
  5. @Rule
  6. public ErrorCollector collector=new ErrorCollector();
  7. @Test
  8. public void test() {
  9. collector.addError(new Throwable("first things went wrong!"));
  10. collector.addError(new Throwable("second things went wrong!"));
  11. }
  12. }

运行结果:

4. Verifier Rule

  • 它是ErrorCollector的父类。当每个测试结束之后会执行ErrorCollector的verify方法,如果执行不通过这个测试会被标记为fail。

[java] view plaincopy

  1. import static org.junit.Assert.*;
  2. import org.junit.Rule;
  3. import org.junit.Test;
  4. import org.junit.rules.Verifier;
  5. public class RuleTest4 {
  6. String sequence="";
  7. @Rule
  8. public Verifier collector=new Verifier(){
  9. @Override
  10. protected void verify(){
  11. System.out.println("this is verify...");
  12. assertEquals("test verify ",sequence);
  13. }
  14. };
  15. @Test
  16. public void test01(){
  17. System.out.println("this is testing 01...");
  18. sequence += "test ";
  19. }
  20. @Test
  21. public void test02(){
  22. System.out.println("this is testing 02...");
  23. sequence="test verify ";
  24. }
  25. }

测试结果:

this is testing 01...
this is verify...
this is testing 02...
this is verify...

test01为 fail,而test02 pass。

5. TestWatchman/TestWatcher Rules

  • 从4.9版本开始,TestWatcher开始代替 TestWatchman。TestWatcher实现了TestRule类,而不是MethodRule类。
  • TestWatchman从4.7版本开始引入,它使用 MethodRule,而MethodRule目前已经弃用。
  • TestWatcher
    不会改变测试的任何行为,提供了
    succeeded、failed、skipped、starting、finished方法用来监控一个测试方法生命周期的各个阶段,所有方法都包含一
    个 org.junit.runner.Description 类型的参数用来描述当前执行的测试。

[java] view plaincopy

  1. import static org.junit.Assert.*;
  2. import org.junit.AfterClass;
  3. import org.junit.Rule;
  4. import org.junit.Test;
  5. import org.junit.internal.AssumptionViolatedException;
  6. import org.junit.rules.TestWatcher;
  7. import org.junit.runner.Description;
  8. import org.junit.runners.model.Statement;
  9. public class RuleTest5 {
  10. private static String watchedLog="";
  11. @Rule
  12. public TestWatcher watchman=new TestWatcher(){
  13. @Override
  14. public Statement apply(Statement base,Description description){
  15. return super.apply(base,description);
  16. }
  17. @Override
  18. protected void succeeded(Description description) {
  19. watchedLog += description.getDisplayName() + " " + "success!\n";
  20. }
  21. @Override
  22. protected void failed(Throwable e, Description description) {
  23. watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n";
  24. }
  25. @Override
  26. protected void skipped(AssumptionViolatedException e, Description description) {
  27. watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n";
  28. }
  29. @Override
  30. protected void starting(Description description) {
  31. super.starting(description);
  32. }
  33. @Override
  34. protected void finished(Description description) {
  35. super.finished(description);
  36. }
  37. };
  38. @Test
  39. public void fails() {
  40. fail();
  41. }
  42. @Test
  43. public void succeeds(){
  44. }
  45. @AfterClass
  46. public static void printlog(){
  47. System.out.println(watchedLog);
  48. }
  49. }

测试结果:

succeeds(com.junit.org.RuleTest5) success!
fails(com.junit.org.RuleTest5) AssertionError

在每一条测试执行完之后,分别调用了 succeeded()和failed()方法对 watchedLog进行处理。当然我们还可以在监控方法里做一些其他的事情。

6. TestName Rule

  • 有了这条规则,即使在测试方法内部我们也可以引用方法名。

[java] view plaincopy

  1. import static org.junit.Assert.*;
  2. import org.junit.Rule;
  3. import org.junit.Test;
  4. import org.junit.rules.TestName;
  5. public class RuleTest6 {
  6. @Rule
  7. public TestName name=new TestName();
  8. @Test
  9. public void testA(){
  10. assertEquals("testA",name.getMethodName());
  11. }
  12. @Test
  13. public void testB(){
  14. assertEquals("testB",name.getMethodName());
  15. }
  16. }

7. Timeout Rule

  • 参考“七 Timeout for tests" 。

8. ExpectedException Rules

  • 参考 ” 四 Exception testing"。

9. ClassRule

@ClassRule 注释扩展了方法级别的规则,它增加了一些静态属性,从而影响整个类。ParentRunner 的任何子类,包括 BlockJUnit4ClassRunner 和 Suite类,都支持 @ClassRule S.

比如说,将ExternalResource 从 @Rule 变成 @ ClassRule,则在整个类里的测试执行过程中它只会执行一次,也就是所有的测试类开始之前会执行 before(),所有的测试类执行结束之后会执行 after()。

[java] view plaincopy

  1. import org.junit.ClassRule;
  2. import org.junit.rules.ExternalResource;
  3. import org.junit.runner.RunWith;
  4. import org.junit.runners.Suite;
  5. import org.junit.runners.Suite.SuiteClasses;
  6. @RunWith(Suite.class)
  7. @SuiteClasses({RuleTest.class,RuleTest2.class,RuleTest3.class})
  8. public class TestSuite01 {
  9. @ClassRule
  10. public static ExternalResource resource= new ExternalResource() {
  11. @Override
  12. protected void before() throws Throwable {
  13. System.out.println("Before Class testing ......");
  14. };
  15. @Override
  16. protected void after() {
  17. System.out.println("After Class testing......");
  18. };
  19. };
  20. }

测试执行结果:

Before Class testing ......
Test Method 1 executing...
Test Method 2 executing...
Test Method 3 executing...
After Class testing......

可以看到,整个过程中ClassRule只执行了一遍。

10  RuleChain

RuleChain 规则允许制定 TestRule的顺序。RuleChain提供一种将多个TestRule串在一起执行的机制,它首先从outChain()方法开始创建一个最外层的TestRule创建的Statement,而后调用round()方法,不断向内层添加TestRule创建的Statement。

[java] view plaincopy

  1. public static class UseRuleChain {
  2. @Rule
  3. public TestRule chain= RuleChain
  4. .outerRule(new LoggingRule("outer rule"))
  5. .around(new LoggingRule("middle rule"))
  6. .around(new LoggingRule("inner rule"));
  7. @Test
  8. public void example() {
  9. assertTrue(true);
  10. }
  11. }

测试结果:

starting outer rule
starting middle rule
starting inner rule
finished inner rule
finished middle rule
finished outer rule

11 Custom Rules

扩展 ExternalResource 规则可以实现大部分需要个性化定制的规则。如果想要获取更过测试类的信息,则需要实现 TestRule接口。

[java] view plaincopy

  1. import org.junit.rules.TestRule;
  2. import org.junit.runner.Description;
  3. import org.junit.runners.model.Statement;
  4. public class IdentityRule implements TestRule {
  5. @Override
  6. public Statement apply(final Statement base, final Description description) {
  7. return base;
  8. }
  9. }

上面只是一个简单的实现。我们还可以在实现TestRule接口的时候建立自己的构造器、添加测试方法、将提供的Statemetn包装成一个新的Statement。

TestRule的一个实现:

[java] view plaincopy

  1. import java.util.logging.Logger;
  2. import org.junit.rules.TestRule;
  3. import org.junit.runner.Description;
  4. import org.junit.runners.model.Statement;
  5. public class TestLogger implements TestRule {
  6. private Logger logger;
  7. public Logger getLogger() {
  8. return this.logger;
  9. }
  10. @Override
  11. public Statement apply(final Statement base, final Description description) {
  12. return new Statement() {
  13. @Override
  14. public void evaluate() throws Throwable {
  15. logger = Logger.getLogger(description.getTestClass().getName() + ‘.‘ + description.getDisplayName());
  16. try {
  17. base.evaluate();
  18. } finally {
  19. logger = null;
  20. }
  21. }
  22. };
  23. }
  24. }

测试中使用:

[java] view plaincopy

  1. import java.util.logging.Logger;
  2. import com.junit.org.TestLogger;
  3. import org.junit.Rule;
  4. import org.junit.Test;
  5. public class MyLoggerTest {
  6. @Rule
  7. public TestLogger logger = new TestLogger();
  8. @Test
  9. public void checkOutMyLogger() {
  10. final Logger log = logger.getLogger();
  11. log.warning("Your test is showing!");
  12. }
  13. }

测试结果:

二月 03, 2015 4:59:34 下午 com.junit.org.MyLoggerTest checkOutMyLogger
警告: Your test is showing!

时间: 2024-11-02 11:26:21

Rules的相关文章

UDEV SCSI Rules Configuration for ASM in Oracle Linux 5 and 6

UDEV SCSI Rules Configuration for ASM in Oracle Linux 5 and 6 For Oracle Automatic Storage Manager (ASM) to use disks, it needs to be able to identify the devices consistently and for them to have the correct ownership and permissions. In Linux you c

【NetApp】在Cmode中使用NetApp powershell SDK工具导入ExportPolicy Rules

1)得到 Export Policy信息: $export_policy = Get-NcExportPolicy -Name testPolicy -VserverContext SVMDes 2)得到Export Rules信息: $export_rules = Get-NcExportRule -Policy testPolicy -VserverContext SVMDes 此处,如果使用$export_policy变量,只能获得defualt Policy的rules信息.如果需要得到

[原]ubuntu14.04 网卡逻辑修改没有文件/etc/udev/rules.d/70-persistent-net.rules

-----问题出现------ 在新装的ubuntu14.04系统中没有发现文件/etc/udev/rule.d/70-persistent-net.rules, 无法修改网络的逻辑名称(即把第一张网卡的名字改为改为eth0,第二张网卡的名字改为eth0) ----------思路----- 1.由于未发现有/etc/udev/rule.d/70-persistent-net.rules文件,重启:重启后也未发现此文件 2.手动执行/lib/udev/write_net_rules;提示缺少变量

The Nine Indispensable Rules for HW/SW Debugging 软硬件调试之9条军规

I read this book in the weekend, and decided to put the book on my nightstand. It's a short and funny book, clear insight and good stories, strongly recommend entry even senior engineers to read it. Introduction This book tells you how to find out wh

[PATCH] ARM: add dtbImage.<dt> and dtbuImage.<dt> rules

转载: http://permalink.gmane.org/gmane.linux.kbuild.devel/8755 This rules are useful for appended device tree conforming to the CONFIG_ARM_APPENDED_DTB kernel option. The rule dtbImage.<dt> is actually just a: cat zImage <dt>.dtb > dtbImage.&

rules of work

it will be more interesting if I can record my feeding about my work rules after reading some books related with the work. walk your talk I like this tip so much since it is what I am short of . Always I take much notice of how others think of me, my

[AngularFire 2] Protect Write Access Using Security Rules

We cannot allow un-auth user to change the database data as they want, for Firebase, it is easy just need to overwirte the rules: { "rules": { ".read": "true", ".write": "auth != null", "courses"

CSS Float nine rules

CSS Float nine rules w3 css float nine rules CSS Float Rule1 CSS Float Rule2 CSS Float Rule3 CSS Float Rule4 CSS Float Rule5 CSS Float Rule6 CSS Float Rule7 CSS Float Rule8 CSS Float Rule9 finally 参考文章 注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出.

Jersey(1.19.1) - Rules of Injection

Previous sections have presented examples of annotated types, mostly annotated method parameters but also annotated fields of a class, for the injection of values onto those types. This section presents the rules of injection of values on annotated t

Make Rules

target: components ls TAB rule main:main.o mytool1.o mytool2.o gcc -o main main.o mytool1.o mytool2.o main.o:main.c mytool1.h mytool2.h gcc -c main.c -I. mytool1.o:mytool1.c mytool1.h gcc -c mytool1.c -I. mytool2.o:mytool2.c mytool2.h gcc -c mytool2.