在JUnit 4中是否有相当于testNG的@BeforeSuite?

时间:2011-12-08 17:50:01

标签: eclipse testing selenium junit junit4

我是测试自动化领域的新手,请原谅我,如果这是一个愚蠢的问题,但谷歌这次失败了。或者至少我读过的任何内容都让我更加困惑。

我在Eclipse中使用JUnit 4和Selenium Webdriver。我有几个测试需要作为套件运行,也需要单独运行。目前,这些测试在自行运行时运行良好。在测试开始时,向测试者/用户呈现输入框,询问他们想要测试的服务器(这是一个字符串变量,它成为URL的一部分)以及他们希望测试的浏览器。在套件中运行测试时,用户会在每次测试开始时被问到这一点,因为很明显,这会被编码到每个@Before方法中。

我如何接受这些值,并将它们传递给每个测试方法?

因此,如果server =“server1”和browser =“firefox”,则firefox是我想要selenium使用的浏览器,我希望它打开的URL是http://server1.blah.com/以用于以下所有测试方法。我一直在使用单独的@Before方法的原因是因为每个测试方法所需的URL略有不同。即每种方法测试不同的页面,例如server1.blah.com/something和server1.blah.com/somethingElse

测试运行正常,我只是不想继续输入值,因为测试方法的数量最终会很大。

如果在testNG中有更简单的方法,我还可以将测试转换为testNG。我认为@BeforeSuite注释可能有用,但现在我不确定。

非常感谢任何建议和批评(建设性的)

4 个答案:

答案 0 :(得分:1)

您可以在JUnit 4 Test invocation的答案中调整解决方案以设置套件的全局变量。

基本上,您扩展Suite以创建MySuite。这将创建一个可从测试中访问的静态变量/方法。然后,在测试中,检查此变量的值。如果已设置,则使用该值。如果没有,那么你得到它。这允许您运行单个测试和一组测试,但您只需要询问用户一次。

因此,您的套件将如下所示:

public class MySuite extends Suite {
    public static String url;

    /**
     * Called reflectively on classes annotated with <code>@RunWith(Suite.class)</code>
     * 
     * @param klass the root class
     * @param builder builds runners for classes in the suite
     * @throws InitializationError
     */
    public MySuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
        this(builder, klass, getAnnotatedClasses(klass));
        // put your global setup here
        MySuite.url = getUrlFromUser();
    }
}

这将在您的套件中使用,如下所示:

@RunWith(MySuite.class)
@SuiteClasses({FooTest.class, BarTest.class, BazTest.class});

然后,在您的测试课程中,您可以在@Before/@After中执行某些操作,或者更好地查看TestRule,或者如果您需要“前后”行为,请查看ExternalResource。 ExternalResource看起来像这样:

public static class FooTest {
    private String url;

    @Rule
    public ExternalResource resource= new ExternalResource() {
        @Override
        protected void before() throws Throwable {
            url = (MySuite.url != null) ? MySuite.url : getUrlFromUser();
        };

        @Override
        protected void after() {
            // if necessary
        };
    };

    @Test
    public void testFoo() {
        // something which uses resource.url
    }
}

您当然可以外部化ExternalResource类,并从多个测试用例中使用它。

答案 1 :(得分:1)

我认为这里有用的TestNG的主要功能不仅仅是@BeforeSuite而是@DataProviders,这使得使用不同的值集运行相同的测试变得微不足道(并且不需要你使用静态,这总是成为一种负担。)

您可能也对TestNG的脚本支持感兴趣,这使得在测试开始之前要求用户输入一些信息是微不足道的here is an example of what you can do with BeanShell

答案 2 :(得分:0)

对测试进行分组以使测试套件具有相同的@Before方法代码可能是有意义的,因此每个单独的测试套件都有一个测试套件。

另一种选择可能是为每个测试使用相同的基本网址,但是通过获取selenium点击进入测试的位置来导航到特定页面。

答案 3 :(得分:0)

如果使用@RunWith(Suite.class),您可以添加@BeforeClass(和@AfterClass)的静态方法,这些方法将在您定义的整个套件之前(和之后)运行。请参阅this question

如果您指的是动态找到的整个类,并且没有使用Suite runner,那么这当然不会有帮助。