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

发布于 2024-12-20 09:25:24 字数 809 浏览 6 评论 0原文

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

我在 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 注释可能有效,但现在我不确定。

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

I'm new to the test automation scene so forgive me if this is a stupid question but google has failed me this time. Or at least anything I've read has just confused me further.

I'm using JUnit 4 and Selenium Webdriver within Eclipse. I have several tests that I need to run as a suite and also individually. At the moment these tests run fine when run on their own. At the start of the test an input box is presented to the tester/user asking first what server they wish to test on (this is a string variable which becomes part of a URL) and what browser they wish to test against. At the moment when running the tests in a suite the user is asked this at the beginning of each test, because obviously this is coded into each of their @Before methods.

How do I take in these values once, and pass them to each of the test methods?

So if server = "server1" and browser = "firefox" then firefox is the browser I want selenium to use and the URL I want it to open is http://server1.blah.com/ for all of the following test methods. The reason I've been using seperate @Before methods is because the required URL is slightly different for each test method. i.e each method tests a different page, such as server1.blah.com/something and server1.blah.com/somethingElse

The tests run fine, I just don't want to keep inputting the values because the number of test methods will eventually be quiet large.

I could also convert my tests to testNG if there is an easier way of doing this in testNG. I thought the @BeforeSuite annotation might work but now I'm not sure.

Any suggestions and criticism (the constructive kind) are much appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

这样的小城市 2024-12-27 09:25:24

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

基本上,您可以扩展 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 中执行某些操作,或者更好地查看 < a href="http://kentbeck.github.com/junit/javadoc/latest/org/junit/rules/TestRule.html" rel="nofollow noreferrer">TestRule,或者如果您想要之前和之后行为,看外部资源。 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 类,并从多个测试用例中使用它。

You can adapt the solution for setting a global variable for a suite in this answer to JUnit 4 Test invocation.

Basically, you extend Suite to create MySuite. This creates a static variable/method which is accessible from your tests. Then, in your tests, you check the value of this variable. If it's set, you use the value. If not, then you get it. This allows you to run a single test and a suite of tests, but you'll only ask the user once.

So, your suite will look like:

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();
    }
}

This would be used in your Suite like so:

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

Then, in your test classes, you can either do something in the @Before/@After, or better look at TestRule, or if you want Before and After behaviour, look at ExternalResource. ExternalResource looks like this:

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
    }
}

You can of course externalize the ExternalResource class, and use it from multiple Test Cases.

北风几吹夏 2024-12-27 09:25:24

我认为 TestNG 在这里有用的主要功能不仅仅是 @BeforeSuite,还有 @DataProviders,这使得使用不同的值集运行相同的测试变得微不足道(并且不需要您使用静态,这总是成为未来的责任)。

您可能还对 TestNG 的脚本支持感兴趣,这使得在测试开始之前询问用户一些输入变得很简单,这里是一个使用 BeanShell 可以执行的操作的示例

I think the main functionality of TestNG that will be useful here is not just @BeforeSuite but @DataProviders, which make it trivial to run the same test with a different set of values (and won't require you to use statics, which always become a liability down the road).

You might also be interested in TestNG's scripting support, which makes it trivial to ask the user for some input before the tests start, here is an example of what you can do with BeanShell.

迎风吟唱 2024-12-27 09:25:24

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

另一种选择可能是为每个测试使用相同的基本 url,但通过让 selenium 单击您想要执行测试的位置来导航到特定页面。

It might make sense to group tests so that the test suite will have the same @Before method code, so you have a test suite for each separate.

Another option might be to use the same base url for each test but navigate to the specific page by getting selenium to click through to where you want to carry out the test.

终弃我 2024-12-27 09:25:24

如果使用 @RunWith(Suite.class),您可以使用 @BeforeClass (和 @AfterClass)添加静态方法,该方法将在 (以及之后)您定义的整个套件。请参阅此问题

如果您引用动态找到的整个类集并且不使用 套件运行程序

If using @RunWith(Suite.class), you can add static methods with @BeforeClass (and @AfterClass), which will run before (and after) the entire Suite you define. See this question.

This of course won't help if you are referring to the entire set of classes found dynamically, and are not using Suite runner.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文