- 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/
在特征方法中,在 when: 中指定特征 Action 。块,其结果在后续 then: 中得到测试堵塞。通常需要准备,这在 given: 中完成条款(或 setup: 或夹具方法)。包含前提条件同样有
我尝试使用 Spy 测试但没有成功。下面的类是一个 Sut。 public class FileManager { public int removeFiles(String director
我希望能够在运行一些自动化测试时记录 spock 功能名称和子句标签。这将有助于在使用 headless 浏览器进行自动化时调试测试问题,特别是 phantomjs。原因是,phantomjs 的行为
如何以编程方式跳过 Spock 框架中的测试?我知道我可以 annotate a test with @Ignore 跳过它,或使用 @IgnoreIf跳过基于环境变量等的测试。但是有没有办法运行任意
下周我将做一个关于 Spock 的演讲,作为演讲的一部分,我需要做一个演示。我以前在一个项目中使用过 Spock,但大约一年左右没有使用它。 演示需要不仅仅是“hello world”类型的演示。我正
下周我将做一个关于 Spock 的演讲,作为演讲的一部分,我需要做一个演示。我以前在一个项目中使用过 Spock,但大约一年左右没有使用它。 演示需要不仅仅是“hello world”类型的演示。我正
为简单起见,我们来看一个非常简单的类: public class TestingClass { public void method1(){ System.out.printl
Spock 只允许从 where 块访问静态变量。 是否有任何解决方法可以在 where 块中使用哪些实例变量? 最佳答案 您可以使用 @Shared 注释实例变量,见 http://spockfra
我正在使用 Spock 框架进行测试,一切都很好,直到今天;我不知道发生了什么。 Intellij 说“配置 Groovy sdk”所以我下载了 groovy sdk 2.4.9 并配置了它,但是在我
我正在为 grails 2.1.1 应用程序的一组现有测试添加第一个 spock 集成测试。使用以下方法运行时,测试运行和测试通过: grails test-app integration:spock
我过去曾在其他项目中使用旧版本的 robolectric 使用 robospock 和 electricspock 对 robolectric 进行过 spock 测试。我的新项目使用 robolec
我正在使用 Maven Surefire 插件运行一组 Spock 测试作为集成测试用例。我知道我们可以使用 @Shared 关键字在单个文件中跨规范的固定装置共享资源。 但是,是否可以在不同的规范文
我正在与: Spock 核心 史波克报告 斯波克 Spring Spring MVC 测试 我有以下代码: def "findAll() Expected"(){ given: "The UR
我正在与: Spock 核心 史波克报告 斯波克 Spring Spring MVC 测试 我有以下代码: @FailsWith(java.lang.AssertionError.class) def
我正在为我的插件创建 Spock 测试 project-plugin我的主要项目名称是 main-project正在使用 project-plugin作为插件。因此,当我为我的插件创建 Spock 测
在JUnit 3中,我可以这样获得当前正在运行的测试的名称: public class MyTest extends TestCase { public void testSomething(
我有一些类似Java的东西: public interface EventBus{ void fireEvent(GwtEvent event); } public class SaveCom
在我的测试中,我有一些只需要在特定情况下运行的特征方法。我的代码看起来像这样: class MyTest extends GebReportingSpec{ def "Feature meth
在我的测试中,我有一些只需要在特定情况下运行的特征方法。我的代码看起来像这样: class MyTest extends GebReportingSpec{ def "Feature meth
我遇到的问题是当我尝试在 then 中验证时阻止已抛出异常,并且已进行模拟调用。 看看下面的设置: class B { def b(A a) { a.a() } } c
我是一名优秀的程序员,十分优秀!