除非使用@Stepwise,否则类无法将模块解析为内容 [英] Class cannot resolve module as content unless @Stepwise used

查看:178
本文介绍了除非使用@Stepwise,否则类无法将模块解析为内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spock类,当作为测试套件运行时,会抛出Unable to resolve iconRow as content for geb.Page, or as a property on its Navigator context. Is iconRow a class you forgot to import?,除非我用@Stepwise注释类.但是,我真的不想让测试执行在第一次失败时停止,这就像@Stepwise一样.

I have a Spock class, that when run as a test suite, throws Unable to resolve iconRow as content for geb.Page, or as a property on its Navigator context. Is iconRow a class you forgot to import? unless I annotate my class with @Stepwise. However, I really don't want the test execution to stop on the first failure, which @Stepwise does.

我尝试使用帖子编写(复制和粘贴)我自己的扩展名,但仍然出现这些错误.它使用了我的扩展程序,因为我添加了一些记录到控制台的日志记录语句.

I've tried writing (copy and pasting) my own extension using this post, but I still get these errors. It is using my extension, as I added some logging statements that were printed out to the console.

这是我的模块之一:

class IconRow extends Module {
    static content = {
        iconRow (required: false) {$("div.report-toolbar")}
    }
}

以及使用它的页面:

class Report extends SomeOtherPage {
    static at = {$("div.grid-container").displayed}

    static content = {
        iconRow { module IconRow }
    }
}

以及失败的测试摘要:

class MyFailingTest extends GebReportingSpec {

    def setupSpec() {
        via Dashboard
        SomeClass.login("SourMonk", "myPassword")
        assert page instanceof Dashboard

        nav.goToReport("Some report name")
        assert page instanceof Report
    }

    @Unroll
    def "I work"() {
        given:
        at Report

        expect:
        this == that

        where:
        this << ["some list", "of values"]
        that << anotherModule.someContent*.@id
    }

    @Unroll
    def "I don't work"() {
        given:
        at Report

        expect:
        this == that

        where:
        this << ["some other", "list", "of values"]
        that << iconRow.columnHeaders*.attr("innerText")*.toUpperCase()
    }
}

当作为套件执行时,I work通过并且I don't work失败,因为它无法将"iconRow"标识为页面内容.如果我切换测试用例的顺序,则I don't work将通过而I work将失败.另外,如果我分别执行每个测试,则它们都会通过.

When executed as a suite I work passes and I don't work fails because it cannot identify "iconRow" as content for the page. If I switch the order of the test cases, I don't work will pass and I work will fail. Alternatively, if I execute each test separately, they both pass.

我尝试过的事情:

  • 从模块内容中添加/删除required: true属性
  • 在类的前面加上模块名称,例如IconRow.iconRow
  • 将我的模块定义为静态@Shared属性
  • 初始化我的setupSpec()
  • 内部和外部的模块
  • 在每个模块的类中创建简单的getter方法以返回该模块,并引用诸如IconRow.getIconRow().columnHeaders*.attr("innerText")*.toUpperCase()
  • 之类的内容
  • 将我的setupSpec()的内容移动到setup()
  • autoClearCookies = false添加到我的GebConfig.groovy
  • 制作一个@Shared Report report变量,并为所有模块加上诸如report.iconRow
  • 之类的前缀
  • Adding/removing the required: true property from content in the modules
  • Prefixing the module name with the class, such as IconRow.iconRow
  • Defining my modules as static @Shared properties
  • Initialize the modules both in and outside of my setupSpec()
  • Making simple getter methods in each module's class that return the module, and referencing content such as IconRow.getIconRow().columnHeaders*.attr("innerText")*.toUpperCase()
  • Moving the contents of my setupSpec() into setup()
  • Adding autoClearCookies = false into my GebConfig.groovy
  • Making a @Shared Report report variable and prefix all modules with that such as report.iconRow

关于最后一个要点的非常特殊的注释-它神奇地解析了具有前缀的模块-因此它不会解析report.IconRow而只会解析iconRow -绝对奇怪,因为如果删除该变量,以前无法正常工作的模块将无法再次解析.我什至尝试声明此变量,然后不添加任何前缀,但这也不起作用.

Very peculiar note about that last bullet point -- it magically resolves the modules that don't have the prefix -- so it won't resolve report.IconRow but will resolve just iconRow -- absolutely bizarre, because if I remove that variable the module that was just previously working suddenly can't be resolved again. I even tried declaring this variable and then not prefixing anything, and that did not work either.

我一直用力撞墙的另一个问题是我也不确定问题在哪里.引发的错误使我相信这是一个项目设置问题,但是单独运行每个功能都可以,因此看来可以很好地解决这些类.

Another problem that I keep banging my head against the wall with is that I'm also not sure of where the problem is. The error it throws leads me to believe that it's a project setup issue, but running each feature individually works fine, so it appears to be resolving the classes just fine.

另一方面,可能是会话和/或Cookie的问题?尽管我还没有看到任何官方文档,但是(从我读过的其他文章和文章中)似乎已经达成共识,即仅使用@Stepwise才能维护功能方法之间的会话.如果是这种情况,为什么我的扩展程序不起作用?几乎是@Stepwise的副本和粘贴,没有skipFeaturesAfterFirstFailingFeature方法(我可以根据需要发布),除非使用@Stepwise在幕后进行了其他工作.

On the other hand, perhaps it's an issue with the session and/or cookies? Although I have yet to see any official documentation on this, it seems to be the general consensus (from other posts and articles I've read) that only using @Stepwise will maintain your session between feature methods. If this is the case, why is my extension not working? It's pretty much a copy and paste of @Stepwise without the skipFeaturesAfterFirstFailingFeature method (I can post if needed), unless there is some other stuff going on behind the scenes with @Stepwise.

为文字墙道歉,但是我已经设法弄清楚了大约6个小时,所以我的脑袋真炸了.

Apologies for the wall of text, but I've been trying to figure this out for about 6 hours now, so my brain is pretty fried.

推荐答案

Geb对@Stepwise有特殊的支持,如果为规范添加了注释,则它不会在每次测试后调用resetBrowser(),而是在规格已完成.参见 github

Geb has special support for @Stepwise, if a spec is annotated with it it does not call resetBrowser() after each test, instead it is called after the spec is completed. See the code on github

因此,基本上,您需要将setupSpec更改为setup,以便它将在每次测试之前执行.

So basically you need to change your setupSpec to setup so that it will be executed before each test.

关于您的观察,如果您仅运行重点测试,则对该测试执行setupSpec,这样它就可以通过.随之而来的问题是,清理工作随后被调用并重置浏览器,从而破坏了随后的测试.

Regarding your observation, if you just run a focused test the setupSpec is executed for that test and thus it passes. The problem arises, that the cleanup is invoked afterwards and resets the browser, breaking subsequent tests.

编辑

我忽略了您对where块的使用,where块中的所有内容都必须是静态可用的(@Shared),因此使用实例级构造将无法正常工作.重置浏览器也会杀死所有引用,因此在无法正常工作之前获取它.基本上,不要在where块中使用Geb对象!

I overlooked your usage of where blocks, everything in the where block needs to be statically (@Shared) available, so using instance level constructs won't work. Resetting the browser will also kill every reference so just getting it before wont work either. Basically, don't use Geb objects in where blocks!

查看您的代码,但是我看不出有任何理由在这里使用数据驱动的测试.

Looking at your code however I don't see any reason to use data driven tests here.

  1. 在正常测试中只需一个断言就可以轻松完成
  2. 对于单元测试来说,仅测试一件事是个好习惯.但是,Geb不是单元测试,而是验收/前端测试.这里的问题是它们比单元测试要慢得多,并且将明智的断言组合到一个测试中是有意义的.


class MyFailingTest extends GebReportingSpec {    
    def setup() {
        via Dashboard
        SomeClass.login("SourMonk", "myPassword")
        assert page instanceof Dashboard

        nav.goToReport("Some report name")
        assert page instanceof Report
    }

    def "I work"() {
        given:
        at Report

        expect:
        ["some list", "of values"] == anotherModule.someContent*.@id
    }

    def "I don't work"() {
        given:
        at Report

        expect:
        ["some other", "list", "of values"] == iconRow.columnHeaders*.attr("innerText")*.toUpperCase()
    }
}

这篇关于除非使用@Stepwise,否则类无法将模块解析为内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆