1.0 Rules

​ Rules允许非常灵活地添加或重新定义一个测试类中每个测试方法的行为。测试人员可以重复使用或扩展下面提供的Rules之一,或编写自己的Rules。

1.1 TestName

​ TestName Rule使当前的测试名称在测试方法中可用。用于在测试执行过程中获取测试方法名称。在starting()中记录测试方法名,在getMethodName()中返回

例如:

import static org.junit.Assert.*;

import org.junit.Rule;

import org.junit.Test;

import org.junit.rules.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.2 TemporaryFolder

​ TemporaryFolder Rule允许创建文件和文件夹,这些文件和文件夹在测试方法结束时被删除(无论通过还是失败)。默认情况下,如果资源不能被删除,则不会抛出异常。

import java.io.*;

import org.junit.Rule;

import org.junit.Test;

import org.junit.rules.TemporaryFolder;

public class HasTempFolder {

@Rule

public 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()可以创建一个随机名字的临时文件;

TemporaryFolder##newFolder() 可以创建一个随机名字的临时目录。

1.3 ExternalResource

​ ExternalResource是一个规则(如TemporaryFolder)的基类,它在测试前设置了一个外部资源(一个文件、套接字、服务器、数据库连接等),并保证在测试后将其拆除。

可以设置测试前后需要做的事情(比如:文件、socket、服务、数据库的连接与关闭)。

public static class UsesExternalResource {

Server myServer = new Server();

@Rule

public 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);

}

}

ExternalResource#before会在每个测试之前处理;#after会在每个测试之后处理;

关于ExternalResource与@Before已经@After等标记步骤的执行顺序,我们会在本文后面部分介绍。

1.4 ErrorCollector

ErrorCollector这个Rule,在出现一个错误后,还可以让测试继续进行下去。

他提供三个方法:

checkThat(final T value, Matcher matcher) checkSucceeds(Callable callable) addError(Throwable error) 前面两个是用来处理断言的,最后一个是添加错误至错误列表中。

看下面例子:

package mytest;

import static org.hamcrest.CoreMatchers.is;

import static org.junit.Assert.assertThat;

import java.util.concurrent.Callable;

import org.junit.Rule;

import org.junit.Test;

import org.junit.rules.ErrorCollector;

public class JUnitCoreErrorControllerRuleTest {

private final int multiplesOf2[] = { 0, 2, 4, 7, 8, 11, 12 };

@Rule

public ErrorCollector errorCollector = new ErrorCollector();

/*

* 下面这个测试,会报告两个failures。这一点和下面的checkSucceeds测试不同

*/

@Test

public void testMultiplesOf2() {

int multiple = 0;

for (int multipleOf2 : multiplesOf2) {

// Will count the number of issues in this list

// - 3*2 = 6 not 7, 5*2 = 10 not 11 : 2 Failures

errorCollector.checkThat(2 * multiple, is(multipleOf2));

multiple++;

}

}

/*

* 下面代码中有两个断言会失败,但每次运行JUnit框架只会报告一个。这一点和上面的checkThat测试不同,可以对比一下。

*/

@Test

public void testCallableMultiples() {

errorCollector.checkSucceeds(new Callable() {

public Object call() throws Exception {

assertThat(2 * 2, is(5));

assertThat(2 * 3, is(6));

assertThat(2 * 4, is(8));

assertThat(2 * 5, is(9));

return null;

}

});

}

/*

* 下面运行时,会报告2个错误

*/

@Test

public void testAddingAnError() {

assertThat(2 * 2, is(4));

errorCollector.addError(new Throwable("Error Collector added an error"));

assertThat(2 * 3, is(6));

errorCollector.addError(new Throwable(

"Error Collector added a second error"));

}

}

运行结果:

Failed tests:

testCallableMultiples(mytest.JUnitCoreErrorControllerRuleTest):

Expected: is <5>

but: was <4>

testMultiplesOf2(mytest.JUnitCoreErrorControllerRuleTest):

Expected: is <7>

but: was <6>

testMultiplesOf2(mytest.JUnitCoreErrorControllerRuleTest):

Expected: is <11>

but: was <10>

Tests in error:

testAddingAnError(tangzhi.mytest.JUnitCoreErrorControllerRuleTest): Error Collector added an error

testAddingAnError(tangzhi.mytest.JUnitCoreErrorControllerRuleTest): Error Collector added a second error

从这个例子,可以看出:

ErrorCollector#checkThat 会报告测试中的每一个failures ErrorCollector#checkSucceeds 只会检查是否成功,如果不成功,只报告第一个导致不成功的failure ErrorCollector#addError 是添加一个错误(error)。

1.5 Verifier

如果,你想在每个测试之后,甚至是在@After之后,想检查些什么,就可以使用Verifier这个Rule.

看例子:

private static String sequence;

public static class UsesVerifier {

@Rule

public Verifier collector = new Verifier() {

@Override

protected void verify() {

sequence += " verify ";

}

};

@Test

public void example() {

sequence += "test";

}

@Test

public void example2() {

sequence += "test2";

}

@After

public void after() {

sequence += " after";

}

}

@Test

public void verifierRunsAfterTest() {

sequence = "";

assertThat(testResult(UsesVerifier.class), isSuccessful());

assertEquals("test after verify test2 after verify ", sequence);

}

从上面例子可以看出:Verifier#verify针对每个测试都会运行一次,并且运行在@After步骤之后。

需要说明:如果某测试出现失败(fail),那么这个测试之后就不会做verify,这一点,可以结合下面的例子看出

1.6 TestWatcher

对测试的每个步骤进行监控。

看例子:

package tangzhi.mytest;

import static org.junit.Assert.*;

import static org.hamcrest.CoreMatchers.*;

import org.junit.After;

import org.junit.Rule;

import org.junit.Test;

import org.junit.rules.TestRule;

import org.junit.rules.TestWatcher;

import org.junit.rules.Verifier;

import org.junit.runner.Description;

import org.junit.runners.model.Statement;

public class WatchmanTest {

private static String watchedLog;

@Rule

public TestRule watchman = new TestWatcher() {

@Override

public Statement apply(Statement base, Description description) {

Statement s = super.apply(base, description);

watchedLog="";

System.out.println("watch apply.");

return s;

}

@Override

protected void succeeded(Description description) {

watchedLog += description.getDisplayName() + " " + "success!";

System.out.println("watch succeed:"+watchedLog);

}

@Override

protected void failed(Throwable e, Description description) {

watchedLog += description.getDisplayName() + " " + e.getClass().getSimpleName();

System.out.println("watch failed:"+watchedLog);

}

@Override

protected void starting(Description description) {

super.starting(description);

System.out.println("watch starting.");

}

@Override

protected void finished(Description description) {

super.finished(description);

System.out.println("watch finished.");

}

};

@Rule

public Verifier collector = new Verifier() {

@Override

protected void verify() {

System.out.println("@Verify:"+watchedLog);

}

};

@Test

public void fails() {

System.out.println("in fails");

assertThat("ssss", is("sss"));

}

@Test

public void succeeds() {

System.out.println("in succeeds");

}

@After

public void after() {

System.out.println("@After");

}

}

1.7 Timeout

对于添加了TimeoutRule 的测试类,当测试类中的测试方法执行超过TimeoutRule 配置的时间时,测试方法执行就会被标记为失败

public class TimeoutRuleTest {

@Rule

public Timeout globalTimeout = Timeout.seconds(5);

@Test

public void timeout() throws InterruptedException {

TimeUnit.SECONDS.sleep(10);

}

@Test

public void onTime() throws InterruptedException {

TimeUnit.SECONDS.sleep(2);

}

}

执行上面测试用例,onTime方法执行通过,timeout()方法则抛出TestTimedOutException:

org.junit.runners.model.TestTimedOutException: test timed out after 5 seconds

还有很多Rule就不一一介绍了

             【下面是我整理的2023年最全的软件测试工程师学习知识架构体系图】

一、Python编程入门到精通

二、接口自动化项目实战 

三、Web自动化项目实战

四、App自动化项目实战 

五、一线大厂简历

六、测试开发DevOps体系 

七、常用自动化测试工具

八、JMeter性能测试 

九、总结(尾部小惊喜)

生命不息,奋斗不止。每一份努力都不会被辜负,只要坚持不懈,终究会有回报。珍惜时间,追求梦想。不忘初心,砥砺前行。你的未来,由你掌握!

生命短暂,时间宝贵,我们无法预知未来会发生什么,但我们可以掌握当下。珍惜每一天,努力奋斗,让自己变得更加强大和优秀。坚定信念,执着追求,成功终将属于你!

只有不断地挑战自己,才能不断地超越自己。坚持追求梦想,勇敢前行,你就会发现奋斗的过程是如此美好而值得。相信自己,你一定可以做到!

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: 

发表评论

返回顶部暗黑模式