草庐IT

java - 参数化单元测试套件

coder 2024-03-08 原文

我正在尝试设置一些参数化测试套件,遗憾的是到目前为止还没有成功。 我有两组参数,我想用所有可能的组合运行多个测试用例(它们在不同的类中)。我试着用 JUnit4 来做,但我无法正确设置它。这将是我的基本想法:

  1. TestSuite1.class 设置一组参数,然后启动 TestSuite2.class
  2. TestSuite2.class 设置第二组参数,然后启动将使用这两个参数的实际测试。

同时,似乎不可能在 RunWith 注解中同时设置 Suite.classParameterized.class (根据 google,Parameterized extends Suite,如果我使用,我通常会收到“找不到可运行的方法”消息。)

我的代码基本上是这样的:

TestSuite1.class:

@RunWith(Parameterized.class)
@Parameterized.SuiteClasses({TestSuite2.class})
//I have tried with @RunWith(Suite.class) and
//@Suite.SuiteClasses({TestSuite2.class}) annotations also - all combinations
public class TestSuite1{

  public TestSuite1(int number) {
    Params.first = number;
  } 

  @Parameters
  public static Collection<Object[]> parameters(){
    Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
    return Arrays.asList(data);
  }
}

TestSuite2.class 看起来与 TestSuite1.class 相同,除了我将 TestCase1.class 添加到套件中而不是 >TestSuite2,并在 Params 中设置另一个变量。

TestCase1.class:

public class TestCase1 {    
  @Test
  public void test1(){
    System.out.println("first: "+Params.first+" second: "+Params.second);
    Assert.assertTrue(true);
  }
}

我对所有想法都持开放态度——即使是 TestNG。我也尝试过(虽然今天是我第一次看到它),但正如我注意到的那样,套件与 JUnit 中的套件有些不同。我不想在测试前设置 XML 文件,我想以编程方式解决所有设置问题。

是否可以使用任何框架实现我正在尝试实现的目标?


更新:使用 TestNG 我有以下代码:

开始类:

public class Start {

public static void main(String[] args){
    TestListenerAdapter tla = new TestListenerAdapter();
    TestNG testng = new TestNG();
    testng.setTestClasses(new Class[] { FirstTest.class, SecondTest.class });
    testng.addListener(tla);
    testng.run();
}
}

参数类:

public class Params {
@DataProvider(name = "param")
public static Object[][] createData() {
    Object[][] data = new Object[][] { { 1 }, { 2}, { 3}, { 4} };
    return data;
  }
}

FirstTest.class:

public class FirstTest {

@Test(dataProvider = "param", dataProviderClass = Params.class)
public static void printIt(int number){
    System.out.println("FirstTest: "+number);
}

}

SecondTest.classFirstTest.class 相同。如果我运行它,它将运行 FirstTest 4 次,然后运行 ​​SecondTest 4 次。我想运行 FirstTest 一次,并使用第一组参数运行 SecondTest 一次。然后我想运行 FirstTestSecondTest 一次,使用第二组参数等。

我已经尝试设置 setPreserveOrder(true),并且还尝试了所有 setParallel 选项。然而,通过这种方式,结果是随机排序的。

(这将是一些 Selenium 测试。我知道测试不应该相互依赖,但这仍然是我想要的方式)

最佳答案

尽管Parameterized延伸Suite ,它的行为完全不同 - 不尊重 Liskov substitution principle .这是因为通常构造函数 Suite(Class<?>, RunnerBuilder)处理 @SuiteClasses注解。但是Parameterized(Class<?>)@Parameters 的处理替换此行为.

如果你想结合Suite的行为和 Parameterized你必须在 JUnit 4 之外寻找。例如你可以实现自己的 Runner就像 Adam Hawkes 已经在 another post here 中提到的那样.

我自己做了同样的事情,拼凑了一个库,为您提供了一个 ParameterizedSuite亚军:https://github.com/PeterWippermann/parameterized-suite

参数化测试套件如下所示:

@RunWith(ParameterizedSuite.class)
@SuiteClasses({OneTest.class, TwoTest.class})
public class MyParameterizedTestSuite {
    @Parameters(name = "Parameters are {0} and {1}")
    public static Object[] params() {
        return new Object[][] {{'A',1}, {'B',2}, {'C',3}};
    }

关于java - 参数化单元测试套件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20891494/

有关java - 参数化单元测试套件的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  3. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  4. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  5. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  6. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  7. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  8. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  9. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  10. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

随机推荐