51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2617|回复: 1
打印 上一主题 下一主题

[转贴] JUnit4 多线程执行测试用例 (下)

[复制链接]
  • TA的每日心情
    无聊
    2024-9-19 09:07
  • 签到天数: 11 天

    连续签到: 2 天

    [LV.3]测试连长

    跳转到指定楼层
    1#
    发表于 2017-8-8 11:15:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    本帖最后由 八戒你干嘛 于 2017-8-8 11:19 编辑

    由于字数限制,此贴分为两贴,此贴为下贴。


    上贴地址⬇️
    JUnit4 多线程执行测试用例 (上)






    只要在单个测试类前,加上注解:@RunWith(MultiThreadRunner.class),就可以并发的执行用例。
    如下图:


    (三)自定义聚合多个类进行多线程执行的Runner有时我们需要聚合同一个模块的测试类,如果使用@RunWith(Suite.class)@SuiteClasses({A.class,B.class}),当类较多时,需要一一列举,效率不高;可以使用ClasspathSuite,支持过滤,将类名符合一定规则的类聚合,官方文档
    实现代码如下:
    1. package com.weibo.concurrent;

    2. import org.junit.experimental.categories.Categories;
    3. import org.junit.extensions.cpsuite.ClasspathSuite;
    4. import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
    5. import org.junit.runner.Runner;
    6. import org.junit.runners.ParentRunner;
    7. import org.junit.runners.model.InitializationError;
    8. import org.junit.runners.model.RunnerBuilder;
    9. import org.junit.runners.model.RunnerScheduler;

    10. import com.weibo.common.MbLogger;

    11. import java.lang.reflect.Method;
    12. import java.util.ArrayList;
    13. import java.util.Arrays;
    14. import java.util.LinkedList;
    15. import java.util.List;
    16. import java.util.Queue;
    17. import java.util.concurrent.CompletionService;
    18. import java.util.concurrent.ExecutorCompletionService;
    19. import java.util.concurrent.ExecutorService;
    20. import java.util.concurrent.Executors;
    21. import java.util.concurrent.Future;
    22. import java.util.concurrent.ThreadFactory;
    23. import java.util.concurrent.TimeUnit;
    24. import java.util.concurrent.atomic.AtomicInteger;

    25. /**
    26. * @author hugang
    27. *
    28. **/
    29. public final class ConcurrentSuite extends ClasspathSuite {

    30.     public static Runner MulThread(Runner runner) {
    31.         if (runner instanceof ParentRunner) {
    32.             // setScheduler(RunnerScheduler scheduler):Sets a scheduler that
    33.             // determines the order and parallelization of children
    34.             // RunnerScheduler:Represents a strategy for scheduling when
    35.             // individual test methods should be run (in serial or parallel)
    36.             ((ParentRunner) runner).setScheduler(new RunnerScheduler() {
    37.                 private final ExecutorService fService = Executors
    38.                         .newCachedThreadPool();

    39.                 // private final ExecutorService fService =
    40.                 // Executors.newFixedThreadPool(10);

    41.                 // Schedule a child statement to run
    42.                 public void schedule(Runnable childStatement) {
    43.                     this.fService.submit(childStatement);
    44.                 }

    45.                 // Override to implement any behavior that must occur after all
    46.                 // children have been scheduled
    47.                 public void finished() {
    48.                     try {
    49.                         this.fService.shutdown();
    50.                         this.fService.awaitTermination(9223372036854775807L,
    51.                                 TimeUnit.NANOSECONDS);
    52.                     } catch (InterruptedException e) {
    53.                         e.printStackTrace(System.err);
    54.                     }
    55.                 }
    56.             });
    57.         }
    58.         return runner;
    59.     }

    60.     public ConcurrentSuite(final Class<?> klass) throws InitializationError {
    61.         // 调用父类ClasspathSuite构造函数
    62.         // AllDefaultPossibilitiesBuilder根据不同的测试类定义(@RunWith的信息)返回Runner,使用职责链模式
    63.         super(klass, new AllDefaultPossibilitiesBuilder(true) {
    64.             @Override
    65.             public Runner runnerForClass(Class<?> testClass) throws Throwable {
    66.                 List<RunnerBuilder> builders = Arrays
    67.                         .asList(new RunnerBuilder[] { ignoredBuilder(),
    68.                                 annotatedBuilder(), suiteMethodBuilder(),
    69.                                 junit3Builder(), junit4Builder() });
    70.                 for (RunnerBuilder each : builders) {
    71.                     // 根据不同的测试类定义(@RunWith的信息)返回Runner
    72.                     Runner runner = each.safeRunnerForClass(testClass);
    73.                     if (runner != null)
    74.                         // 方法级别,多线程执行
    75.                         return MulThread(runner);
    76.                 }
    77.                 return null;
    78.             }
    79.         });

    80.         // 类级别,多线程执行
    81.         setScheduler(new RunnerScheduler() {
    82.             private final ExecutorService fService = Executors
    83.                     .newCachedThreadPool();

    84.             @Override
    85.             public void schedule(Runnable paramRunnable) {
    86.                 // TODO Auto-generated method stub
    87.                 fService.submit(paramRunnable);
    88.             }

    89.             @Override
    90.             public void finished() {
    91.                 // TODO Auto-generated method stub
    92.                 try {
    93.                     fService.shutdown();
    94.                     fService.awaitTermination(Long.MAX_VALUE,
    95.                             TimeUnit.NANOSECONDS);
    96.                 } catch (InterruptedException e) {
    97.                     e.printStackTrace(System.err);
    98.                 }
    99.             }

    100.         });
    101.     }

    102. }
    复制代码

    新建一个聚合的IntegrationBeijingOneTests.java文件:
    1. @RunWith(ConcurrentSuite.class)
    2. @ClassnameFilters({"com.weibo.cases.xuelian.*Test", "!.*RemindTest","com.weibo.cases.maincase.*Xuelian"})
    3. @Concurrent
    4. public interface IntegrationBeijingOneTests {

    5. }
    复制代码

    再建一个suite文件,XuelianTestSuite.java:
    1. package com.weibo.cases.suite;
    2. import org.junit.experimental.categories.Categories;
    3. import org.junit.runner.RunWith;
    4. import org.junit.runners.Suite.SuiteClasses;

    5. @RunWith(Categories.class)
    6. @SuiteClasses( IntegrationBeijingOneTests.class )
    7. public class XuelianTestSuite {

    8. }
    复制代码

    直接运行XuelianTestSuite.java即可,执行过程如下:


    写在最后:设计测试用例时需考虑线程安全。
    建议(本组内用例):
    1.账号的使用,同一个测试类中每个测试方法之间需使用不同测试账号(之前未考虑并发,串行执行时方法间使用同样账号,没有影响),咱们组V4的用例共1516个,假设每个用例使用3个账号,则同时执行用例时,则需4548个账号,现库里有1617个账号,可能需要增加用户(空间换时间); 当然也可以控制并发执行测试方法的数量,来减少用户的使用,比如可以指定同时5个(可调)测试方法并发执行,当然,执行时间上就会相应的增加。
    2.非final的全局变量,全改写到测试方法内定义,变成局部变量。

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2018-3-22 09:02
  • 签到天数: 117 天

    连续签到: 1 天

    [LV.6]测试旅长

    2#
    发表于 2017-8-25 09:09:21 | 只看该作者
    @Concurrent,我这为什么不识别
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-14 11:02 , Processed in 0.060301 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表