#-*- coding: UTF-8 -*- import time import unittest import sys class DemoTest(unittest.TestCase): def setUp(self): …. Def test_a(self): ……… Def test_b(self): ……… Def test_c(self): ……… Def test_d(self): ……… Def tearDown(self): ……… if __name__ == '__main__': suite = unittest.TestLoader().loadTestsFromTestCase(DemoTest) unittest.TextTestRunner(verbosity=2).run(suite) ``` 上面的示例是包含四个测试用例的一个测试用例集,在我们执行这个测试文件后,四个测试用例的执行顺序是随机的。如果这几个测试用例有依赖关系,则会影响你们用例的执行,于是我在想能不能控制一下测试用例的执行顺序呢?虽然测试用例相互之间不能有依赖关系,可是这算是一个尝试吧!我在网上查到一个方法,是适用于junit的: 换种顺序来执行TestCase(Junit适用) Junit的TestCase,总是按固定的顺序执行的. 正如你在Eclipse中跑Run As Junit Test, 无论你跑多少次, TestCase的执行顺序都是一致的,可重复的. 这就导致一个问题, TestCase之间的独立性无法保证. 例如下面一个Test类中的2个TestCase: |
public class DaoTest {
@Test public void test_count() { dao.insert(new User("root", "123456")); assertEquals(1, dao.count(User.class)); } @Test public void test_insert() { dao.clear(User.class, null); dao.insert(new User("admin", "123456")); assertEquals(1, dao.count(User.class)); } |
}
如果先执行test_count()然后执行test_insert(),两个TestCase都能通过. 但如果先执行test_insert(),然后执行test_count(),则test_count()会失败. 所以,有必要去打乱TestCase的默认执行顺序,以暴露出TestCase本身的问题. TestCase更可靠,才能让主代码更可靠. 我实现了一个简单的方式,使用的是Junit的公开API, 测试过4.3和4.8.2,均可使用: //得到所有带@Test的方法,这里用的是Nutz的资源扫描,反正你能得到全部Test类就行 |
List list = Scans.me().scanPackage("org.nutz"); List reqs = new ArrayList(); Map reqMap = new HashMap(); for (Class clazz : list) { Method[] methods = clazz.getMethods(); for (Method method : methods) { if (method.getAnnotation(Test.class) != null) { //将单个TestCase(即一个Test Method),封装为Junit的Test Request Request req = Request.method(clazz, method.getName()); reqs.add(req); reqMap.put(req , method);//在最终打印测试结果时,方便查找具体出错的Method } } } // 因为reqs 是一个List,我们可以按需调整TestCase的顺序 // 正序 //nothing change. // 反序Collections.reverse(reqs) // 乱序Collections.shuffle(reqs) //把执行顺序保存下来,方便重现执行顺序 try { FileWriter fw = new FileWriter("./test_order.txt"); for (Request request : reqs) { fw.write(reqMap.get(request).toString()); fw.write("\n"); } fw.flush(); fw.close(); } catch (IOException e) {} //到这里, List已经按我们预期的方式排好,可以执行测试了 final TestResult result = new TestResult(); RunNotifier notifier = new RunNotifier(); notifier.addListener(new RunListener() { //需要设置一个RunListener,以便收集测试结果 public void testFailure(Failure failure) throws Exception { result.addError(asTest(failure.getDescription()), failure.getException()); } public void testFinished(Description description) throws Exception { result.endTest(asTest(description)); } public void testStarted(Description description) throws Exception { result.startTest(asTest(description)); } public junit.framework.Test asTest(Description description) { return new junit.framework.Test() { public void run(TestResult result) { throw Lang.noImplement(); } public int countTestCases() { return 1; } }; } }); //来吧,执行之!! for (Request request : reqs) { request.getRunner().run(notifier); } //接下来,就是打印结果了. System.out.printf("Run %d , Fail %d , Error %d \n", result.runCount(), result.failureCount(), result.errorCount()); if (result.failureCount() > 0) { //断言失败的TestCase Enumeration enu = result.failures(); while (enu.hasMoreElements()) { TestFailure testFailure = (TestFailure) enu.nextElement(); System.out.println("--Fail------------------------------------------------"); System.out.println(testFailure.trace()); testFailure.thrownException().printStackTrace(System.out); } } if (result.errorCount() > 0) { //抛异常的TestCase Enumeration enu = result.errors(); while (enu.hasMoreElements()) { TestFailure testFailure = (TestFailure) enu.nextElement(); System.out.println("--ERROR------------------------------------------------"); System.out.println(testFailure.trace()); testFailure.thrownException().printStackTrace(System.out); } } |
来, 考验一下你的TestCase吧!! 让它在乱序中多次执行. Nutz按这种思路,已经爆出几个Bug(当然,我已经迅速fix了) https://github.com/nutzam/nutz/blob/master/test/org/nutz/AdvancedTestAll.java python中不好用,于是只好想一下其他的方法了。我想是不是可以把每个测试用例变成函数,然后再写一个函数来顺序调用它们呢? 这个方法虽然可以控制顺序,可以也有一定的风险,如果出错了,不会按测试用例给报错,不能准确地统计出测试用例地正确率!如果全部通过则没有问题,可是影响报告的结果,需要想办法来美化一下报告。 修改后的代码如下: |
-- coding: UTF-8 --
import time
import unittest
import sys
class DemoTest(unittest.TestCase):
def setUp(self): …. |
Def a(self):
………
Def b(self):
………
Def c(self):
………
Def d(self):
………
Def test_demo(self):
a()
b()
c()
d()
Def tearDown(self):
………
ifname == 'main':
suite = unittest.TestLoader().loadTestsFromTestCase(DemoTest)
unittest.TextTestRunner(verbosity=2).run(suite)
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。