抽奖活动的中奖事件是个随机事件,用大量的手动测试来检验中奖概率的正确性显然不可取,除了手工对中奖流程,后续处理的校验外,可以和开发配合,使用接口来测试中奖的概率是否符合预期的设计要求。
1.思路:
(1)开发提供中奖的接口,get该接口(此处需要向开发详细了解),每次随机返回以下四个结果:
0--表示未抽中
1--表示抽中1等奖
2--表示抽中2等奖
3--表示抽中3等奖
(2)使用for循环,多次请求该接口,并使用testNG框架中自带的设置多次执行方法和处理多线程的方法,使多个方法并发运行,缩短执行时间,来模拟大数据量下的中奖事件。
(3)对(2)中的中奖事件进行数据处理,获取各类中奖事件的概率。
2.代码
用例代码 LotteryTestCase.java 如下:
1 package com.krplus.api.autotest.testcase; 2 import org.apache.http.HttpEntity; 3 import org.apache.http.client.methods.CloseableHttpResponse; 4 import org.apache.http.client.methods.HttpGet; 5 import org.apache.http.impl.client.CloseableHttpClient; 6 import org.apache.http.impl.client.HttpClients; 7 import org.apache.http.util.EntityUtils; 8 import org.testng.annotations.Test; 9 /** 10 * Created by wyy on 2016/4/18. 11 */ 12 public class LotteryTestCase { 13 @Test(invocationCount =10, threadPoolSize = 5) 14 //invocationCount----表示执行本方法的次数,在此表示每执行本方法10次 15 //threadPoolSize-----表示开启的多线程个数,和方法执行次数有关, 此处表示开启5个线程,每2个方法共用同一个线程,多个方法并发同时执行,节省运行的时间成本///不过使用该设置一般用于下面为单个方法执行,此处使用了for循环,所以此处设置不是很有效,可忽略 16 public void testLottery() throws Exception { 17 int fail = 0; 18 int first = 0; 19 int second = 0; 20 int third = 0; 21 float perfail=0; 22 float perfirst=0; 23 float persecond=0; 24 float perthird=0; 25 int m=100; //设置请求接口get的次数 26 // 循环使用get方法获取中奖接口的数据,获得中奖的类型数据 27 for (int i = 0; i <m; i++) { 28 CloseableHttpClient httpClient = HttpClients.createDefault(); 29 HttpGet get = new HttpGet("http://**********") //第一次中奖接口,先单个在浏览器中运行看结果是否有异常 30 // HttpGet get = new HttpGet("http://**********"); //第二次中奖接口 31 CloseableHttpResponse response = httpClient.execute(get); 32 try { 33 HttpEntity entity = response.getEntity(); 34 String result = EntityUtils.toString(entity); 35 int res=Integer.parseInt(result); //将中奖的类型为 string类型转化为int类型, 36 if(res==0){ 37 fail=fail+1; 38 // perfail=(float)fail/m;//获取中奖失败的概率,放在此处会导致每次for循环都执行一次,所以应该放到for循环外 39 }else if(res==1){ 40 first=first+1; 41 }else if(res==2){ 42 second=second+1; 43 }else{ 44 third=third+1; 45 } 46 } finally { 47 response.close(); 48 } 49 } 50 perfail=(float)fail/m;//获取中奖失败的概率 51 perfirst=(float)first/m; 52 persecond=(float)second/m; 53 perthird=(float)third/m; 54 System.out.println("-------中奖次数--------"); 55 System.out.println("中奖失败的次数为"+fail); 56 System.out.println("中一等奖的次数为"+first); 57 System.out.println("中二等奖的次数为"+second); 58 System.out.println("中三等奖的次数为"+third); 59 System.out.println("-------中奖概率--------"); 60 System.out.println("中奖失败的概率为"+perfail); 61 System.out.println("中一等奖的概率为"+perfirst); 62 System.out.println("中二等奖的概率为"+persecond); 63 System.out.println("中三等奖的概率为"+perthird); 64 } 65 }
在testNG.xml中设置用例的路径,执行即可。综上可看,请求接口1000次,每个方法执行100次请求,执行10个该方法,每个方法的结果如下:
1 [TestNG] Running: 2 D:krplus-api-test estcase estcaseLottery esNG.XML 3 -------中奖次数-------- 4 中奖失败的次数为16 5 中一等奖的次数为2 6 中二等奖的次数为9 7 中三等奖的次数为73 8 -------中奖概率-------- 9 中奖失败的概率为0.16 10 中一等奖的概率为0.02 11 中二等奖的概率为0.09 12 中三等奖的概率为0.73
之后和设计中的概率进行对比即可!
在实践过程中的确发现通过这种接口测试可以发现概率和接口方面的问题:
1.第一次中奖时,即使运行1000次,一等奖中奖次数也是0,后来是因为开发重写代码不完整所致
2.运行时抛异常,运行单个接口发现有问题,如下:
其实还是蛮有用的是不撒哈~O(∩_∩)O!
当然具体情况需要具体分析,谁知道后面的 抽奖活动会是甚样设计~