首页 > 其他 > 详细

Rules

时间:2015-07-11 14:51:59      阅读:139      评论:0      收藏:0      [点我收藏+]
我们之前处理异常的时候用到过Rules,当然还有很多其他规则。Rules允许弹性的添加或者重定义测试方法的行为。测试者可以重复使用或者扩展下面的某一个Rules,也可以写一个属于自己的规则。

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

技术分享

基本的规则有:

1.TemporaryFolder Rule

  • 该规则建立的文件或者文件夹会在测试方法结束之后自动删除(不管测试pass还是fail)。默认情况下,即使资源删不掉也不会抛出异常。
  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.   
  7. public class RuleTest {  
  8.     @Rule  
  9.     public TemporaryFolder folder=new TemporaryFolder();  
  10.   
  11.     @Test  
  12.     public void test() throws IOException {  
  13.         File aFile=folder.newFile("myfile.txt");  
  14.         File aFolder=folder.newFolder("subfolder");  
  15.     }  
  16. }  
  • 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用来对外部资源进行管理,包括在测试之前进行外部资源准备,测试之后对测试资源进行回收等工作。在创建测试文件、连接服务器、准备数据库连接等情况下用的比较多。
  1. import org.junit.Rule;  
  2. import org.junit.Test;  
  3. import org.junit.rules.ExternalResource;  
  4.   
  5. public class RuleTest2 {  
  6.       
  7.     @Rule  
  8.     public ExternalResource external = new ExternalResource()  
  9.     {  
  10.         protected void before() throws Throwable  
  11.         {  
  12.             System.out.println("Perparing test data.");  
  13.             System.out.println("Test data is Ready!");  
  14.         }  
  15.   
  16.         protected void after()  
  17.         {  
  18.             System.out.println("Cleaning test data.");  
  19.         }  
  20.     };  
  21.       
  22.     @Test  
  23.     public void test1()  
  24.     {  
  25.         System.out.println("Test 1 executing...");  
  26.     }  
  27.       
  28.     @Test  
  29.     public void test2()  
  30.     {  
  31.         System.out.println("Test 2 executing...");  
  32.     }  
  33.       
  34.     @Test  
  35.     public void test3()  
  36.     {  
  37.         System.out.println("Test 3 executing...");  
  38.     }  
  39. }  

运行结果:

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 规则允许测试在第一个问题出现的时候继续执行,然后执行完之后一次性汇报结果。比如说测试一个表格里的所有的行,在第一行发现错误之后继续执行,直到所有 的错误都发现才停止,然后一次性汇报所有的结果。
  1. import org.junit.Rule;  
  2. import org.junit.Test;  
  3. import org.junit.rules.ErrorCollector;  
  4.   
  5. public class TestRule3 {  
  6.     @Rule  
  7.     public ErrorCollector collector=new ErrorCollector();  
  8.     @Test  
  9.     public void test() {  
  10.         collector.addError(new Throwable("first things went wrong!"));  
  11.         collector.addError(new Throwable("second things went wrong!"));  
  12.     }  
  13. }  

运行结果:

技术分享


4. Verifier Rule

  • 它是ErrorCollector的父类。当每个测试结束之后会执行ErrorCollector的verify方法,如果执行不通过这个测试会被标记为fail。
  1. import static org.junit.Assert.*;  
  2. import org.junit.Rule;  
  3. import org.junit.Test;  
  4. import org.junit.rules.Verifier;  
  5.   
  6. public class RuleTest4 {  
  7.     String sequence="";  
  8.       
  9.     @Rule  
  10.     public Verifier collector=new Verifier(){  
  11.         @Override  
  12.         protected void verify(){  
  13.             System.out.println("this is verify...");  
  14.             assertEquals("test verify ",sequence);  
  15.         }  
  16.     };  
  17.       
  18.     @Test  
  19.     public void test01(){  
  20.         System.out.println("this is testing 01...");  
  21.         sequence += "test ";  
  22.     }  
  23.       
  24.     @Test  
  25.     public void test02(){  
  26.         System.out.println("this is testing 02...");  
  27.         sequence="test verify ";  
  28.     }  
  29. }  

测试结果:

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 类型的参数用来描述当前执行的测试。 
  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.   
  10. public class RuleTest5 {  
  11.     private static String watchedLog="";  
  12.       
  13.     @Rule  
  14.     public TestWatcher watchman=new TestWatcher(){  
  15.         @Override  
  16.         public Statement apply(Statement base,Description description){  
  17.             return super.apply(base,description);  
  18.         }  
  19.           
  20.         @Override  
  21.         protected void succeeded(Description description) {  
  22.           watchedLog += description.getDisplayName() + " " + "success!\n";  
  23.         }  
  24.   
  25.         @Override  
  26.         protected void failed(Throwable e, Description description) {  
  27.           watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n";  
  28.         }  
  29.   
  30.         @Override  
  31.         protected void skipped(AssumptionViolatedException e, Description description) {  
  32.           watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n";  
  33.         }  
  34.   
  35.         @Override  
  36.         protected void starting(Description description) {  
  37.           super.starting(description);  
  38.         }  
  39.   
  40.         @Override  
  41.         protected void finished(Description description) {  
  42.           super.finished(description);  
  43.         }  
  44.     };  
  45.   
  46.     @Test  
  47.     public void fails() {  
  48.         fail();  
  49.     }  
  50.       
  51.     @Test  
  52.     public void succeeds(){  
  53.           
  54.     }  
  55.       
  56.     @AfterClass  
  57.     public static void printlog(){  
  58.           System.out.println(watchedLog);  
  59.     }  
  60. }  

测试结果:

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

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

6. TestName Rule

  • 有了这条规则,即使在测试方法内部我们也可以引用方法名。
  1. import static org.junit.Assert.*;  
  2. import org.junit.Rule;  
  3. import org.junit.Test;  
  4. import org.junit.rules.TestName;  
  5.   
  6. public class RuleTest6 {  
  7.     @Rule  
  8.     public TestName name=new TestName();  
  9.       
  10.     @Test  
  11.     public void testA(){  
  12.         assertEquals("testA",name.getMethodName());  
  13.     }  
  14.       
  15.     @Test  
  16.     public void testB(){  
  17.         assertEquals("testB",name.getMethodName());  
  18.     }  
  19. }  

7. Timeout Rule

  • 参考“七 Timeout for tests" 。

8. ExpectedException Rules

  • 参考 ” 四 Exception testing"。

9. ClassRule

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

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

  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.   
  7. @RunWith(Suite.class)  
  8. @SuiteClasses({RuleTest.class,RuleTest2.class,RuleTest3.class})  
  9. public class TestSuite01 {  
  10.   
  11.       @ClassRule  
  12.       public static ExternalResource resource= new ExternalResource() {  
  13.         @Override  
  14.         protected void before() throws Throwable {  
  15.           System.out.println("Before Class testing ......");  
  16.         };  
  17.   
  18.         @Override  
  19.         protected void after() {  
  20.           System.out.println("After Class testing......");  
  21.         };  
  22.       };  
  23. }  

测试执行结果:

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

 

  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.   
  8.     @Test  
  9.     public void example() {  
  10.         assertTrue(true);  
  11.     }  
  12. }  

测试结果:

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

11 Custom Rules

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

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

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

TestRule的一个实现:

  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.   
  6. public class TestLogger implements TestRule {  
  7.   private Logger logger;  
  8.   
  9.   public Logger getLogger() {  
  10.     return this.logger;  
  11.   }  
  12.   
  13.   @Override  
  14.   public Statement apply(final Statement base, final Description description) {  
  15.     return new Statement() {  
  16.       @Override  
  17.       public void evaluate() throws Throwable {  
  18.         logger = Logger.getLogger(description.getTestClass().getName() + ‘.‘ + description.getDisplayName());  
  19.         try {  
  20.           base.evaluate();  
  21.         } finally {  
  22.           logger = null;  
  23.         }  
  24.       }  
  25.     };  
  26.   }  
  27. }  

测试中使用:

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

测试结果:

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

Rules

原文:http://www.cnblogs.com/miniren/p/4638483.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!