标签: parametrized-testing

如何在 Kotlin 中使用 MethodSource 编写嵌套 ParametrizedTest?

我正在学习如何使用 JUnit 5 在 Kotlin 中编写测试。当我编写 Java 时@Nested,我喜欢使用 、@ParametrizedTest等功能。@MethodSource但是当我切换到 Kotlin 时,我遇到了一个问题:

我想出了如何使用

但当我把这些放在一起时,我得到了

这里不允许使用伴随对象。

在内部类里面。


测试重现错误

internal class SolutionTest {
    @Nested
    inner class NestedTest {
        @ParameterizedTest
        @MethodSource("testCases")
        fun given_input_should_return_expected(input: Int, expected: Int) {
            // assert
        }

        // error in below line
        companion object {
            @JvmStatic
            fun testCases(): List<Arguments> {
                return emptyList()
            }
        } …
Run Code Online (Sandbox Code Playgroud)

kotlin junit5 parametrized-testing

8
推荐指数
2
解决办法
1736
查看次数

使用纯 Kotlin 函数作为 Junit5 方法源

我很好奇在 Kotlin 中,在 Junit5 的参数化测试中,我是否可以使用类外的方法作为 @MethodSource。

我知道在 Kotlin 中使用 @MethodSource 的 2 种方法 - 伴随对象和 @TestInstance(TestInstance.Lifecycle.PER_CLASS)。我想知道是否可以通过不同的方式来完成,例如通过在类之外声明一个方法并使用一些注释?我试图这样做,但它不起作用,我想知道是否可以做类似的事情。

class GenerationStatusTest {

    @ParameterizedTest
    @MethodSource("provideStatusesToTest")
    internal fun shouldStatusesHaveExpectedAbilities(generationStatus: GenerationStatus, assertions:(GenerationStatus)->Unit) {
        assertions(generationStatus)
    }
}

fun provideStatusesToTest(): Stream<Arguments> {
    return Stream.of(
            Arguments.of(WAITING, canDoNothing),
            Arguments.of(PROCESSING, canDoNothing)
    )
}
Run Code Online (Sandbox Code Playgroud)
org.junit.platform.commons.JUnitException: Could not find factory method [provideStatusesToTest] in class [com.test.enums.GenerationStatusTest]
    at org.junit.jupiter.params.provider.MethodArgumentsProvider.lambda$getMethod$4(MethodArgumentsProvider.java:83)
Run Code Online (Sandbox Code Playgroud)

kotlin junit5 parametrized-testing

7
推荐指数
2
解决办法
2564
查看次数

使用 JUnit 5 的 @ParametrizedTest 与 @TestFactory Stream&lt;DynamicTest&gt; 之间的区别是什么?

首先,它们在 Junit 5 动态测试指南的结论中是什么意思?

参数化测试可以替代本文中的许多示例。但是,动态测试与参数化测试不同,因为它们支持完整的测试生命周期,而参数化测试不支持。

我浏览了JUnit 5 – 参数化测试,相信我理解了语法级别的差异,并且相信我明白了这一点:

此外,动态测试在如何生成输入和如何执行测试方面提供了更大的灵活性。

但是看起来,为什么有人更喜欢参数化测试而不是动态测试?

java junit5 parametrized-testing

5
推荐指数
1
解决办法
1317
查看次数

如何从 pytest 固定装置正确返回列表以用于参数化?

我正在尝试构建一个小的 pytest 测试,以确保 redis 中存在所有预期的键。我有一个预期键列表,我将其存储为 YML 文件。测试本身将查询 redis 以确保列表中的每个预期键都存在。

最初,我将此设置为test_keys.py文件中的一个巨大列表。这是这样设置的:

expected_keys = ['key1','key2','key3']
@pytest.mark.parametrize('expected_key', expected_keys)
def test_expected_key(expected_key):
    ...
Run Code Online (Sandbox Code Playgroud)

这有效。由于我想为 redis 环境的其他一些检查复制这种类型的测试,因此我不想将包含几百个键的多个列表放入这些文件中。

我想我可以将它们提取到 YML 文件中并通过装置加载键。

我的夹具看起来像这样:

@pytest.fixture
def expected_keys_fixture():
    with open('expected_keys.yml'), 'r') as f:
        return yaml.safe_load(f)['keys']
Run Code Online (Sandbox Code Playgroud)

YML 看起来像这样:

keys:
  - key1
  - key2
  - key3
Run Code Online (Sandbox Code Playgroud)

我的测试装饰器更改为:

@pytest.mark.parametrize("expected_keys", [
    (pytest.lazy_fixture('expected_keys_fixture'))
])
def test_expected_key(expected_key):
    ...
Run Code Online (Sandbox Code Playgroud)

我正在pytest-lazy-fixture为此使用该软件包。

我在这里expected_keys遇到的问题是现在等于预期键的整个列表。当静态列表在我的测试文件中时,它不再是每个单独的密钥。

我试图按照 Oleh Rybalchenko 的回答建议去做

@pytest.mark.parametrize("expected_keys", pytest.lazy_fixture('expected_keys_fixture')
)
def test_expected_key(expected_key):
    ...
Run Code Online (Sandbox Code Playgroud)

但是,这失败了TypeError: 'LazyFixture' object is not …

python fixtures pytest parametrized-testing

5
推荐指数
1
解决办法
1517
查看次数

如何使用 ParameterizedTest 中参数的嵌套属性定义显示名称(name = #{index} multip {0[0]} x {0[1]} = {0[2]})

我无法确定它是否是一个缺失的功能,请参阅JUnit 问题 1154我在那里的评论,或者只是我无法正确编写 JUnit5 中的名称语法@ParameterizedTest。鉴于这个问题已经开放了三年,恐怕我等不及得到答案,甚至无法等到那里的实施,所以我也想在这里问。

在我的示例 ParameterizedTest 中,我使用@MethodSource,它返回一个整数数组流,我想仅使用这些数组的属性,而不是{arguments}使用 时所有相同的属性{0}。这里很难用语言解释,最好使用下面的代码示例。

package net.delphym.unittests;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

class DynamicTestCreationTestParam {
    private static Stream<int[]> data() {
        return Stream.of(new int[][] { {1, 2, 2}, {5, 3, 15}, {121, 4, 484} });
    }

    @DisplayName("Multiplication test")
    @ParameterizedTest(name = "#{index} for {arguments}: {0} x {1} = {2}")
    @MethodSource("data")
    void testWithStringParameter(int[] data) {
        MyClass tester = new …
Run Code Online (Sandbox Code Playgroud)

java junit5 parametrized-testing

5
推荐指数
1
解决办法
1221
查看次数

在 Python 中动态参数化多个测试

我正在尝试使用 Pytest 编写动态测试套件,其中测试数据保存在单独的文件中,例如 YAML 文件或 .csv。我想运行多个测试,所有这些测试都从同一个文件进行参数化。假设我有一个测试文件test_foo.py,如下所示:

import pytest

@pytest.mark.parametrize("num1, num2, output", ([2, 2, 4], [3, 7, 10], [48, 52, 100]))
def test_addnums(num1, num2, output):
    assert foo.addnums(num1, num2) == output

@pytest.mark.parametrize("foo, bar", ([1, 2], ['moo', 'mar'], [0.5, 3.14]))
def test_foobar(foo, bar):
    assert type(foo) == type(bar)
Run Code Online (Sandbox Code Playgroud)

使用参数化装饰器,我可以在 pytest 中运行多个测试,并且按预期工作:

test_foo.py::test_addnums[2-2-4] PASSED                                                                                                                                                            
test_foo.py::test_addnums[3-7-10] PASSED                                                                                                                                                           
test_foo.py::test_addnums[48-52-100] PASSED                                                                                                                                                        
test_foo.py::test_foobar[1-2] PASSED                                                                                                                                                               
test_foo.py::test_foobar[moo-mar] PASSED                                                                                                                                                           
test_foo.py::test_foobar[0.5-3.14] PASSED
Run Code Online (Sandbox Code Playgroud)

但我想动态地参数化这些测试。我的意思是,我想将所有测试的测试数据写入一个单独的文件中,以便当我运行 pytest 时,它将应用我写入每个测试函数的所有测试数据。假设我有一个类似于以下内容的 YAML 文件:

test_addnums:
  params: [num1, num2, output]
  values:
    - [2, 2, 4]
    - [3, …
Run Code Online (Sandbox Code Playgroud)

python pytest python-3.x parametrized-testing

5
推荐指数
1
解决办法
3637
查看次数

PyTest:在运行时动态生成测试名称

当我使用夹具运行测试时,我想在运行时动态命名测试@pytest.mark.parametrize("value",values_list)。例如:

values_list=['apple','tomatoes','potatoes']

@pytest.mark.parametrize("value",values_list)
def test_xxx(self,value):
    assert value==value
Run Code Online (Sandbox Code Playgroud)

我想看到的最终结果是 3 个测试,名称如下:

测试苹果

测试番茄

测试土豆

我尝试查看 pytest 文档,但我还没有发现任何可能阐明这个问题的内容。

python pytest python-3.x parametrized-testing

4
推荐指数
1
解决办法
3648
查看次数

在 pytest 中使用双参数化将测试标记为 xfail

我有一个 pytest 测试,可以针对两个不同的数据库测试多个输入。我使用参数化标记两次来做到这一点:

@pytest.mark.parametrize(
    "input_type",
    [
        pytest.param("input_1"),
        pytest.param("input_2"),
    ],
)
@pytest.mark.parametrize(
    "db_type",
    [
        pytest.param("db_type_1"),
        pytest.param("db_type_2"),
    ],
)
Run Code Online (Sandbox Code Playgroud)

我所经历的只是当运行input_1db_type_2例如)测试由于错误而失败但使用不同的数据库传递运行相同的输入时。input_1我只想将和组合标记db_type_2为 xfail,而所有其他组合不应标记为 xfail。我找不到如何做到这一点。

如果标记db_type_2为 xfail:

@pytest.mark.parametrize(
    "db_type",
    [
        pytest.param("db_type_1"),
        pytest.param("db_type_2", marks=pytest.mark.xfail)
    ],
)
Run Code Online (Sandbox Code Playgroud)

所有输入都将失败,这不是我正在寻找的行为。有人可以帮我解决这个问题吗?

python pytest parametrized-testing

4
推荐指数
1
解决办法
775
查看次数

如何使用“fixture”和“parametrize”为pytest测试设置环境变量

我有 pytest 测试,其结果可能取决于环境变量。我想测试它们的这个环境变量的多个值。

我只想有一个设置此环境变量的固定装置,但我希望能够为每个测试而不是每个固定装置配置这些值。

我该怎么做?

python environment-variables pytest python-3.x parametrized-testing

4
推荐指数
1
解决办法
5617
查看次数