优化测试脚本中,提高效率是主要目的之一,但是往往效率提升是最难的,因为无从下手。但其实我们平时的测试脚本中有一部分是很容易优化提升效率的,那就是I/O部分。我们常规的做法是在脚本运行前使用JUnit的@Before或者@BeforeClass来进行各种I/O操作,例如读写数据库、读写磁盘文件等,很多时候是为了准备测试数据,这些预置条件花费的时间常常比整个脚本的运行时间都要长,如果能缩短这部分操作的时间,那么效率很得到很大的提升。
优化的方法很简单,就是将这部分操作异步处理。以数据准备为例,我们最常见的做法是将数据保存在excel中,然后读取excel后再插入数据库,这里就涉及一次磁盘I/O和一次网络I/O,但是准备出来的数据一般并不是在测试脚本的第一步就会被用到,所以可以把预置条件异步执行,与测试脚本并行执行,再需要预置条件处理结果的时候再去获取。
下面我用一个页面自动化脚本为例来介绍如何提高这部分操作的效率,这段代码用来校验淘宝交易过程中的付款环节,既然是校验付款,那么在预置条件中应该要准备一个未付款状态的订单数据。
优化前我们的脚本如下:
Java代码
1.import java.util.concurrent.ExecutionException; 2.import java.util.concurrent.TimeoutException; 3. 4.import org.junit.Before; 5.import org.junit.Test; 6. 7. 8.public class AsyncSample { 9. 10. private long orderId; 11. 12. @Before 13. public void createOrder() { 14. //准备订单数据 15. orderId = 0L; //赋值准备好的订单号 16. } 17. 18. @Test 19. public void test() throws InterruptedException, ExecutionException, TimeoutException { 20. //步骤一:登录页面 21. //步骤二:打开已买到订单页面 22. //步骤三:根据订单号定位页面元素位置 23. //步骤四:付款 24. //断言:验证付款结果 25. } 26. 27.} |
上面的脚本中,最耗时的应该在@Before的createOrder方法中,下面来优化这个方法。
Java代码
1.import java.util.concurrent.Callable; 2.import java.util.concurrent.ExecutionException; 3.import java.util.concurrent.ExecutorService; 4.import java.util.concurrent.Executors; 5.import java.util.concurrent.Future; 6.import java.util.concurrent.TimeUnit; 7.import java.util.concurrent.TimeoutException; 8. 9.import org.junit.AfterClass; 10.import org.junit.Before; 11.import org.junit.Test; 12. 13. 14.public class AsyncSample { 15. 16. private static final ExecutorService single = Executors.newSingleThreadExecutor(); 17. 18. private Future<Long> future; 19. 20. @Before 21. public void createOrder() { 22. future = single.submit(new Callable<Long>() { 23. 24. @Override 25. public Long call() throws Exception { 26. long orderId = 0L; 27. //准备订单数据 28. return orderId; //返回订单ID 29. } 30. }); 31. } 32. 33. @AfterClass 34. public static void shutdown() { 35. single.shutdownNow(); 36. } 37. 38. @Test 39. public void test() throws InterruptedException, ExecutionException, TimeoutException { 40. //步骤一:登录页面 41. //步骤二:打开已买到订单页面 42. long orderId = future.get(10, TimeUnit.SECONDS); //步骤三:从异步任务中获取订单号 43. //步骤四:根据订单号定位页面元素位置 44. //步骤五:付款 45. //断言:验证付款结果 46. } 47. 48.} |
为了清楚的说明方法,并没有写太多的代码,都以注释说明取代。可以看到在步骤三时才需要预置条件中准备的测试数据,但是正常情况下,在登录和打开已买到页面的过程中,订单数据已经准备好了,步骤三可以直接拿到订单号然后继续后面的步骤。
相比原来的脚本,我们充分利用了登录和打开页面这段时间完成了数据准备的工作,所以整个数据准备的时间完全没有了,脚本效率提升是非常明显的。
当然,也可以将异步的方法作一些封装使其更简洁和易用。另外,对于异步方法的使用需要把握好度,避免大量使用降低代码的可读性和可维护性。