- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 Spock 的新手,目前正在切换到它,但我继承了大量需要重新使用的测试配置文件。每个配置文件都是一个 JSON,与 Spec 类同名。对于每个测试方法,都有一个带有参数的映射列表,例如:
LoginSpec.json:
{
"My first test": [
{
"user": "user_one",
"role": "ADMIN"
},
{
"user": "user_two",
"role": "REPORTER",
"other_param": "other"
}
],
"Some Other Test Method": [
{
"url": "/lab1",
"button_name": "Show news popup"
}
]
}
TestNG 允许我在数据提供程序方法中传递测试方法名称,因此我可以根据测试类名称和测试方法名称返回映射列表。我的基类中只有一个数据提供者方法:
public Object[][] getData(String method) {
DataReader reader = new JsonReader()
return reader.parse(packageFullName, getClass().simpleName, method)
}
作为这种方法的结果,我得到了一个 map 数组,用于每个测试迭代。然后我将此方法指定为 DataProvider:
@Test(dataProvider = "getData", priority = 1)
void EULA_1(Map data) { <====
Pages.login.openLoginPage()
Pages.login.logIn(data.user) <====
...
}
这非常有效:在基类中声明 ones,它会自动接收测试并提供测试数据。
问题是有没有办法在 Spock 测试中应用类似的方法?
我想在我的基类中有一些 getData() 方法,我可以在其中根据测试方法名称读取测试参数,然后将它们传递到 where block 中。
我尝试使用我的 json 阅读器,如下所示:
def "My first test"() {
setup:
println(data)
when:
...
then:
...
where:
data = dataReader.parse("JobE2E", "LoginSpec.json", "My first test")
}
这个例子给了我所需的 map 列表,但有两个问题:
总结:实现接收测试方法名称并返回 map 列表的数据提供程序的最佳方法是什么?
最佳答案
您可以使用这种方法解决 data
的问题:
data << dataReader.parse('JobE2E', "${getClass().name}.json", 'My first test')
它将迭代 map 列表,因此每次测试迭代都将仅由该 map 参数化。
可以通过以下方式获取当前测试名称:
specificationContext.currentFeature.name
当前迭代名称为:
specificationContext.currentIteration.name
但是两者都不能在 where
部分访问,因为它在测试本身之前执行,其中只有来自共享上下文的值可用。
所以这里恐怕您必须手动输入测试名称。
更新:我在where
部分为您找到了如何获取特征名称的解决方案。它是通过使用拦截器的自己的扩展实现的。
功能详细信息容器:
class FeatureDetails {
String name
}
扩展注解:
import org.spockframework.runtime.extension.ExtensionAnnotation
import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@ExtensionAnnotation(FeatureDetailsExtension.class)
@interface ShareFeatureDetails {
}
带有内联拦截器实现的 Spock 扩展:
import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension
import org.spockframework.runtime.model.FeatureInfo
class FeatureDetailsExtension extends AbstractAnnotationDrivenExtension<ShareFeatureDetails> {
def featureDetails = new FeatureDetails()
@Override
void visitFeatureAnnotation(ShareFeatureDetails annotation, FeatureInfo feature) {
feature.addInterceptor({ i ->
featureDetails.name = feature.name
feature.spec.allFields.each { f ->
if (f.type == FeatureDetails.class && f.readValue(i.getInstance()) == null) {
f.writeValue(i.getInstance(), featureDetails)
}
}
i.proceed()
})
}
}
扩展的用法示例:
class DataProviderSpec extends Specification {
@Shared
FeatureDetails currentFeature
@Unroll("Test #data.a * 2 = #data.b")
@ShareFeatureDetails
def 'test'() {
when:
println data
then:
data.a * 2 == data.b
where:
data << loadData()
}
@Unroll("Test #data.a * 3 = #data.b")
@ShareFeatureDetails
def 'another test'() {
when:
println data
then:
data.a * 3 == data.b
where:
data << loadData()
}
def loadData() {
// this is hard coded example
println "${getClass().name}.${currentFeature.name}"
if ('test' == currentFeature.name) return [[a: 1, b: 2], [a: 2, b: 4]]
if ('another test' == currentFeature.name) return [[a: 3, b: 9], [a: 4, b: 12]]
return []
// ... use load from data file (JSON, YAML, XML, ...) instead:
// return dataReader.parse("${getClass().name}.json", currentFeature.name)
}
}
上面例子的输出:
DataProviderSpec.test
[a:1, b:2]
[a:2, b:4]
DataProviderSpec.another test
[a:3, b:6]
[a:4, b:8]
第一个想法是在规范类中仅使用带注释的 String featureName
字段,但存在一个问题,即 visitFeatureAnnotation()
方法在每次调用期间与不同的规范实例一起工作loadData()
方法每次在第一个实例上执行。
注意:您还可以使用 @Unroll
注释添加具有特定于当前迭代的值的描述。例如:
@Unroll("Test #data.a * 2 = #data.b")
def 'test'() {
setup:
...
when:
...
then:
data.a * 2 == data.b
where:
data << getData('test')
}
def getData(String methodName) {
if ('test' == methodName) return [[a: 1, b: 2], [a: 2, b: 4]]
...
}
将产生:
Test 1 * 2 = 2
Test 2 * 2 = 4
关于java - Spock 中 TestNG 数据提供者的模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53173193/
我想多次运行一个测试用例。在testng.xml中可以配置吗?如果在测试方法中添加循环,则每次运行的结果将不会受到testng报告的影响。 最佳答案 您不能通过xml来执行此操作,但是可以在@Test
我在 TestNG 中尝试了一些使用硬断言和软断言的示例。虽然软断言按预期工作,但我遇到了硬断言的问题。 根据我从互联网上读到的信息-如果硬断言失败,它不会执行其他测试。 由于 ffPageEleme
我能够在 Eclipse 中完美地运行 testng。但是,我想使用命令行(Win 8)运行它,如不同论坛上所述。以下是我尝试处理错误的不同方法 - 1. java -cp "D:\testng\te
假设我有一个可以并行或串行执行的套件。但是,这样做的决定要留给运行时。启动此套件的常见方法如下: TestNG runner = new TestNG(); if (runInParallel())
如何获得执行TESTNG的方法所花费的时间? sample 测试: @Test(threadPoolSize = 100, invocationCount = 100) public void tes
我发现有一个选项可以通过surefire插件将参数设置为testng xml,然后可以从命令行发送参数。 [...] org.apache.maven.plug
我正在尝试使用这样的命令行运行 testng 测试: C:\Documents and Settings\Administrateur\Bureau\automatic tests testNG>ja
我正在尝试从我的套件文件中删除 testng 参数,因为它们在多个套件中都需要。例如,我有 2 个测试套件,upgrades.xml 和 features.xml。我创建了第三个文件,paramete
目标:并行独立运行 2 个类,其中每个测试将方法名称存储到一个变量中,该变量稍后可以在测试中访问。 问题:当测试并行运行时,它们开始在它们之间共享数据,从而破坏测试。 如果您看到控制台输出这是错误的:
好的,请引用 TestNG doc我可以运行测试 依次 (默认在测试套件中)或在 平行使用 . 现在这是我的 TestNG 配置
我正在尝试从命令行运行TestNG,但这给了我错误。 有人可以告诉我我要去哪里错吗? java -cp C:/TestNG目录/testng-6.2.jar;C:\project目录\src\com\
情况和问题 我有几个测试类,每个类都有几个测试方法。所有测试在后台使用相同的测试数据库。每个测试类初始化其数据库内容,然后在几个测试方法中测试内容。 当我单独运行每个测试时,它们都通过了。但是当我同时
如何让我的 TestNG 报告显示报告中控制台输出的链接?我以前见过 TestNG 这样做,但我现在正在做的一个项目没有显示任何输出,而且我在任何地方都找不到任何说明如何打开它的信息。我尝试在 tes
如果断言失败,如何在 TestNG 中继续执行测试?如何在 TestNG 的 HTML 报告中报告失败? 当我运行以下代码时,执行了断言之后的行,但在报告中未列出断言失败: @Test public
如果断言失败,如何在 TestNG 中继续执行测试?如何在 TestNG 的 HTML 报告中报告失败? 当我运行以下代码时,执行了断言之后的行,但在报告中未列出断言失败: @Test public
我在每个 wiki 使用 TestNG + ReportNG instructions在 gradle 中(我固定在食谱上,因为默认示例对我不起作用)。 我想以某种方式在 TestNG 中捕获控制台输
如何使用 TestNG 自动化功能测试,跨越多个 Java 进程? 我对尝试使用 TestNG 而不是 JUnit 产生了兴趣,因为它声称不仅仅是为单元测试而设计的,但我还没有找到具体的例子来说明如何
如何在测试用例的运行时获取当前正在运行的套件名称?我正在使用下面显示的代码来获取当前套件名称。 监听类: public class SuiteListener implements ISuiteLis
我正在使用 Selenium Webdriver 和 Java 设计一个用于测试的定制自动化框架。 现在出于报告的目的,我正在尝试将 TestNG 框架与我的项目集成。 现在我有一个基于 GUI 的界
出于某种原因,我必须使用旧的 TestNG 库,它没有 "getCurrentXmlTest()).getAllParameters()" API 我应该如何使用testng-5.4-jdk15.ja
我是一名优秀的程序员,十分优秀!