当前位置: 首页 > 知识库问答 >
问题:

在Cypress中,每个工作之前和之前是如何进行的?

陶璞
2023-03-14

我想我错过了一些关于之前和之前的方式。我有一个规范文件,加载数据从夹具在之前的方法。这些数据中的一部分被用在之前的函数中,然后又被用在之前的函数中,以及在实际的测试中。规范文件包含2个测试。第一个测试按预期执行。第二个失败,因为beForeeach表示来自夹具的值之一未定义。

我的期望是,如果我加载数据从一个夹具在之前的方法,它应该是可用于所有测试规范文件

在执行“检查按钮栏的状态”时,测试beforeach函数中的window.console.log(this.user_数据)是否按预期输出用户_数据。

执行“提交表单”测试时,beforeach函数中的window.console.log(this.user_数据)输出未定义,测试停止。

我错过了什么?

describe('Customer Profile', () => {

    before(function () {
        window.console.log('Enter the before function')
        // Load the fixture data. Its asynchronous so if we want to use it right here and now
        // we have to put the things that use inside a callback to be executed after the data
        // loaded. 
        cy.fixture('user').as('user_data').then(function (){
            window.console.log('Fixture has loaded the user data')
            cy.visit('/LaunchPad/login')
            // Fill out the login form
            cy.get('input[name="username"]').type(this.user_data.username)
            cy.get('input[name="password"]').type(this.user_data.password)
            cy.get('button[type="submit"]').click()
        })
    })

    beforeEach(function(){
        window.console.log('Enter the beforeEach function')
        window.console.log(this.user_data)
        // Preserve the cookies for all tests in this suite
        Cypress.Cookies.preserveOnce('SESSION')
        // Open the profile view
        cy.visit('/Manager/'+this.user_data.org+'/config/company-profile')
    })

    it('Check the state of the button bar', function(){
        window.console.log('Running test of button bar')
        cy.get('section.content-header > h1').contains('Company Profile Details')
        // Check the state of the action bar and its buttons
        cy.get('section.action-bar').get('label.btn.btn-sm.btn-primary').contains('Save')
            .should('have.attr', 'for', 'submit-form')
            .should('have.attr', 'tabindex', '0')

        cy.get('section.action-bar').get('#resetButton').contains('Reset')
            .should('have.attr', 'type', 'reset')
            .should('have.attr', 'value', 'Reset')
            .should('have.class', 'btn btn-sm btn-default')

        cy.get('section.action-bar').get('a.btn.btn-sm.btn-default').contains('Cancel')
            .should('have.attr', 'href', '/Manager/'+this.user_data.org+'/')

        cy.get('section.action-bar').get('a').contains('Delete').should('not.exist')

    })

    // This form has no required fields and no validation. So just pick a value or two
    // submit the form and verify the banner is correct
    it('Submit form', function(){
        window.console.log('Running the submit form test')
        cy.fixture('company_profile').as('company_profile')
        cy.get('#companyProfileDto.name').type(this.company_profile.name)
    })


})

根据卡洛斯·阿尔弗雷多(Carlos Alfredo)的回答,在阅读了更多的内容后,我更新了这篇文章。1.我仍然需要访问登录页面。我们使用csrf和誓言,试图得到工作的例子只是花了太多的时间。2.我必须为会话cookie使用白名单,因为preserveOnce根本不起作用。

这是我现在有的文件。它访问登录页面一次,并获取会话cookies设置。这两项测试按预期进行。

支持/index.js

before(function(){
    cy.login('bob', 'password')
    cy.fixture('user').as('user_data')
    cy.fixture('company_profile').as('company_profile')
})

beforeEach(function(){
    window.console.log('Enter the global beforeEach function')
    // Load the fixture data

})

support/commands.js

/*
    We visit the login form despite what the best practise recommendation is because
    we have OAUTH redirects and a CSRF token to deal with. Since the majority of the
    examples and working use cases provided dont deal with those scenarios this is 
    the best I can do at the moment. 
*/
Cypress.Commands.add('login', (username, password, options = {}) => {
    cy.visit('/LaunchPad/login')
    // Fill out the login form
    cy.get('input[name="username"]').type(username)
    cy.get('input[name="password"]').type(password)
    cy.get('button[type="submit"]').click()
})
/*
    We are white listing the cookie because Cypress.Cookies.preserveOnce('SESSION') 
    does not work. https://github.com/cypress-io/cypress/issues/2952

    Because we are forcing Cypress to not clear the cookies, you will have to close
    the test window after the suite is completed other wise the Vision360 apps will
    think your session is alive.
*/
Cypress.Cookies.defaults({
    whitelist: 'SESSION'
})

集成/customer\u profile/customer\u profile\u spec.js

describe('Customer Profile', () => {

    it('Check the state of the button bar', function(){
        window.console.log('Running test of button bar')

        cy.visit('/Manager/'+this.user_data.org+'/config/company-profile')

        cy.get('section.content-header > h1').contains('Company Profile Details')
        // Check the state of the action bar and its buttons
        cy.get('section.action-bar').get('label.btn.btn-sm.btn-primary').contains('Save')
            .should('have.attr', 'for', 'submit-form')
            .should('have.attr', 'tabindex', '0')

        cy.get('section.action-bar').get('#resetButton').contains('Reset')
            .should('have.attr', 'type', 'reset')
            .should('have.attr', 'value', 'Reset')
            .should('have.class', 'btn btn-sm btn-default')

        cy.get('section.action-bar').get('a.btn.btn-sm.btn-default').contains('Cancel')
            .should('have.attr', 'href', '/Manager/'+this.user_data.org+'/')

        cy.get('section.action-bar').get('a').contains('Delete').should('not.exist')

    })

    // This form has no required fields and no validation. So just pick a value or two
    // submit the form and verify the banner is correct
    it('Submit form', function(){
        window.console.log('Running the submit form test')
        cy.visit('/Manager/'+this.user_data.org+'/config/company-profile')

        // Fill and submit the form
        cy.get('input#companyProfileDto\\.name').clear().type(this.company_profile.name)
        cy.get('section.action-bar').get('label.btn.btn-sm.btn-primary').contains('Save').click()

        // Check the response
        cy.get('.callout-success').contains('Your changes are saved.')
        cy.get('input#companyProfileDto\\.name').should('have.value', this.company_profile.name)
    })

})

共有3个答案

丁念
2023-03-14

如果您保存了一组会话cookie,最快的方法可能是硬编码/暴力将它们强制进入生活,例如:

  beforeEach(() => {
    Cypress.Cookies.preserveOnce('SESSION')     // remember cookies for this session:
    cy.setCookie('logged_in_cookie_name', '000000000000000000000') // hard coded session cookie
    cy.setCookie('security_salt_etc', '000000000000000000000') // its like a revokable password but more secure
  })
  after(() => {    // logout!
    cy.clearCookies()
  })
蒋英博
2023-03-14

看起来cypress正在为每个测试清理夹具。

摘自《柏树指南》关于“悬空之州”

... 事实上,当测试结束时,Cypress不会清理自己的内部状态。我们希望您在测试结束时处于悬挂状态!测试结束时,诸如存根、间谍甚至路线之类的东西都不会被移除。这意味着您的应用程序在运行Cypress命令时或在测试结束后手动使用它时的行为将相同。

该页面中没有关于fixtures的明确说明,但是,看起来它正在发生,并且fixtures也被清理了。这就是beforeach()在第一个测试中起作用(检查按钮栏的状态),因为它正好在before()之后运行。对于第二个测试,在钩子之前在中设置的所有内容都消失了,现在beforeach()正在尝试获取从未定义过的装置。

希望能有帮助。

其他一些建议:

  • 将您的登录作为一个自定义命令来执行是一个很好的做法,只需使用请求即可跳过UI

公孙新觉
2023-03-14

我遇到了一个几乎和你以前一样的问题。

在下一个代码块之前运行。

describe("Some test", function() {
    before(function() {
        //something ...
        cy.request('POST', loginUrl, loginInformation).its('body').as('currentUser')
    })

    // this.currentUser exists here
    it("Should foo", function() {
    })

    // this.currentUser doesn't exist here
    it("Should bar", function() {
    })
})

我修复了将()之前的语句从描述范围中移出的问题。

before(function() {
    //something ...
    cy.request('POST', loginUrl, loginInformation).its('body').as('currentUser')
})

describe("Some test", function() {     
    // this.currentUser exists here
    it("Should foo", function() {
    })

    // this.currentUser also exists here
    it("Should bar", function() {
    })
})

我希望这能帮助你解决你的问题。

 类似资料:
  • 我想在测试套件中的每个测试之前和之后运行其他设置和拆卸检查。我看过赛程,但不确定它们是否是正确的方法。我需要在每次测试之前运行设置代码,并且需要在每次测试后运行拆卸检查。 我的用例是检查没有正确清理的代码:它会留下临时文件。在我的设置中,我将检查文件,在拆解中我也会检查文件。如果有额外的文件,我希望测试失败。

  • 问题内容: 我有一个测试套件,可以在其中退出系统并在中关闭浏览器。我尝试使用每种测试方法都使用Selenium拍摄失败的测试屏幕截图。我手动检查了它只在每个之前运行,但我想在它之前和之后进行设置。我找不到简单的解决方案。任何帮助将不胜感激。 我得到的输出是 问题答案: 由于规则的设置方式,因此不能有@before之后或@after之后的规则。您可以想到放在测试方法上的诸如shell之类的规则。要进

  • 问题内容: 我正在使用jQuery和jQuery UI。我体验到用户有时会多次触发ajax调用,因为触发调用的按钮/链接在单击后不会立即被禁用。为了防止这种情况的发生,现在我在“ beforeSend”操作中禁用按钮/链接。 这是典型的Ajax Call对我来说的样子: 但是我不想在每个Ajax调用中添加此按钮禁用逻辑。有什么办法全局定义每次在/ after和ajax-call之前都会被调用的函数

  • javax。servlet。Filter对象既可以用于身份验证(在需要完成任何servlet工作之前,过滤器需要捕获请求),也可以用于XSLT转换(servlet需要完全生成内容)。什么时候执行? 我知道这取决于实现(取决于web容器),但这似乎是所有人都需要解决的问题。 也许在web容器的每个过滤器注册的地方都设置了一个配置选项? 其他: 此外,什么控制过滤器的执行顺序?为什么FooFilter

  • 问题内容: 我正在尝试了解join()的代码流。 正如我在多次运行程序后所观察到的那样,输出始终是首先执行的,并且它将在任何时候都不会进行任何上下文切换。我的理解清楚吗? 我观察到一些东西,如果不使用连接,将在线程执行的任何地方执行,这意味着我在程序的输出之间看到输出,但是总是在线程t3 之后执行。我怀疑这是语法开始之前的问题,因此它不应该跟随t3 / t1线程完成吗?这有意义还是我想念的东西?

  • 我正在Postman中编写测试,我有多个请求分组如下: > 某些测试标题: > 创建用户(一组“预请求”): 发送一些创建用户所需的请求,这些请求是运行测试所必需的 对已创建用户的一些操作(这里我正在测试测试标题中的内容) 一个或多个请求 < li >创建用户(一组“预先请求”,与测试1中相同。): < ul > < li >发送创建用户、运行测试所需的一些请求 一个或多个请求 总的来说,当我想测