使用多个顺序页面测试 webapp 时出错
Error when testing webapp with multiple sequential pages
我正在测试一个 ASP.NET 网络应用程序(我无权访问其代码),它具有多个连续页面,在 Cypress 脚本中包含以下相关部分:
describe("Calculation", function() {
// ...
context("Pages", function() {
// ...
// Page 1
it("With all inputs", function() {
cy.visit(url)
// ... setting input fields ...
cy.get(next).click()
cy.get('.stg-error-mark').should('have.length', 0)
})
// Page 2
it("No selection", function() {
cy.get(next).click()
cy.get('.stg-error-mark').should('have.length', 2)
})
})
})
第 2 页 it(...)
的命令日志包含:
...
- CLICK
(FORM SUB) --submitting form-- ← Page 2 looks fine in Cypress' App Preview.
(PAGE LOAD) --page loaded-- ← The webapp shows the error below in the App Preview.
...
Error
The input transaction was automatically cancelled because it was not continued for too long. Please start again.
如果 Page 1
没有在 Page 2
的 it(...)
中被 visit()
编辑,webapp 似乎缺少一些内部状态。
我知道将所有相关的页面代码部分放入 (describe
-global) function
s 并越来越多地调用它们,这样在每个测试中总是从 Page 1
开始。但是,由于这个应用程序有 33 个不同的功能路径,有 5 到 6 个连续页面(取决于用户在前一页上的输入),我想避免这种代码膨胀、混乱、容易出错和耗时的函数链接——并且全局变量是魔鬼。
更新
从理论到实践,这是功能路径图:
+------ Seite 1 -------+----- Seite 2 -----+------ Seite 3 ------+------ Seite 4 ------+- Seite 5.1 -+- Seite 5.2 -+
| Wohneinheiten | Fördermodell | 1. Wohneinheit | 2. Wohneinheit | Berechnung | Berechnung |
| 2/4 | 8/2 | 12/10 | 6/5 | Input | Output |
| | | | | | |
| Wohneinheiten: | ▼ Modell | Heizwärmebedarf: | | | |
| +- <no> --->(X) | +-▼ Passiv ------>-- HWB: ----------------------------------->-------------> |
| | | | | +- !]0..10] | | | |
| +- WE1: --->(X) | | | +--->(X) | | | |
| | | | | | | | |
| +- WE2: --->(X) | +-▼ Punkte ------>-- HWB: ----------------------------------->-------------> |
| | | | | +- !]10..49] | | | |
| +- WE1: | | | +--->(X) | | | |
| | +- AV-V: -------->--+ | | | | |
| | | | | +-▼ PV ---------------------------------->-------------> |
>--+ | | | +-▼ Solar ------------------------------->-------------> |
| | | +-▼ Niedrig ----->--+-x WRL --------------------------------->-------------> |
| | | | | +- <no> --->(X) | | | |
| +- WE2: | | | | | | |
| | +- AV-V: --->(X) | +-▼ Niedrigst --->--▼ Heizsystem ---------------------------->-------------> |
| | | | | +-▼ Elektrisch | | | |
| | | +-▼ <no> --->(X) | +-▼ PV2kWp | | | |
| | | | | +--->(X) | | | |
| | | | +-o WRL | | | |
| | | | +--->(X) | | | |
| +- WE1: | | | | | |
| +- WE2: | ▼ Modell | Heizwärmebedarf: | Heizwärmebedarf: | | |
| +- AV-V: ----->--+-▼ Passiv ------>-- HWB: ------------->-- HWB: ------------->-------------> |
| | | | +- !]0..10] | +- !]0..10] | | |
+----------------------+ | | +--->(X) | +--->(X) | | |
| | | | | | |
| +-▼ Punkte ------>-- HWB: ------------->-- HWB: ------------->-------------> |
| | | +- !]10..49] | +- !]10..49] | | |
| | | +--->(X) | +--->(X) | | |
| | | | | | |
| +-▼ Niedrig ----->--+-▼ PV ----------->--+-▼ PV ----------->-------------> |
| | | +-▼ Solar ---------> +-▼ Solar --------->-------------> |
| | | +-x WRL -----------> +-x WRL ----------->-------------> |
| | | +- <no> --->(X) | +- <no> --->(X) | | |
| | | | | | |
| +-▼ Niedrigst --->--▼ Heizsystem ------>--▼ Heizsystem ------>-------------> |
| | | +-▼ Elektrisch | +-▼ Elektrisch | | |
| +-▼ <no> --->(X) | +-▼ PV2kWp | +-▼ PV2kWp | | |
| | | +--->(X) | | +--->(X) | | |
| | +-x WRL | +-x WRL | | |
| | +--->(X) | +--->(X) | | |
+-------------------+---------------------+---------------------+-------------+-------------+
Legend:
: ...... Textbox
.. ..... Interval
▼ ...... Dropdown-Listbox or selection
x,o .... Checkbox (checked, unchecked)
<no> ... No input or selection
! ...... Not
(X) .... Error
> ...... Proceed to page or error
现在一切都清楚了,不是吗? (: 好的,它看起来有点绿色,在编辑器中看起来更高更宽。)
在 Seite 1
.
输入 WE2
的情况下,下部的 Seite 3
和 Seite 4
相同且重复
(我不是反对者)
我不确定你的问题到底是什么 -- 你需要提供更多信息:
- 错误来自哪里,是什么触发了它?
- 你确定不拆state/cookies/etc。在测试用例之间?
无论哪种方式,通常您不应该在一个测试用例依赖于前一个测试用例的情况下在测试用例之间共享状态,并且测试用例必须按给定顺序 运行。测试用例(it
)应该相互独立,自给自足。
不遵守此最佳做法会导致难以维护的复杂测试用例。您也无法切换 it.only
来测试单个案例,依此类推。
当您不拥有整个代码库(在团队项目中)时,这一点尤其重要,因为有人可能会更改测试的方式 运行(例如,清除测试之间的状态;随机化测试顺序... ).
我通过我在问题中提到的试图避免的方式解决了这个问题:将相关代码外部化到 describe
-global functions
。这就是我上面提到的所有内容,但至少是 DRY。
describe("Calculation", function() {
let P1withAllInputs = function() {
cy.visit(url)
// ... setting input fields ...
cy.get(next).click()
cy.get('.stg-error-mark').should('have.length', 0)
}
context("Page 1", function() {
// ...
it("With all inputs", function() {
P1withAllInputs()
})
})
context("Page 2", function() {
P1withAllInputs()
// ...
it("No selection", function() {
cy.get(next).click()
cy.get('.stg-error-mark').should('have.length', 2)
})
})
})
我正在测试一个 ASP.NET 网络应用程序(我无权访问其代码),它具有多个连续页面,在 Cypress 脚本中包含以下相关部分:
describe("Calculation", function() {
// ...
context("Pages", function() {
// ...
// Page 1
it("With all inputs", function() {
cy.visit(url)
// ... setting input fields ...
cy.get(next).click()
cy.get('.stg-error-mark').should('have.length', 0)
})
// Page 2
it("No selection", function() {
cy.get(next).click()
cy.get('.stg-error-mark').should('have.length', 2)
})
})
})
第 2 页 it(...)
的命令日志包含:
...
- CLICK
(FORM SUB) --submitting form-- ← Page 2 looks fine in Cypress' App Preview.
(PAGE LOAD) --page loaded-- ← The webapp shows the error below in the App Preview.
...
Error
The input transaction was automatically cancelled because it was not continued for too long. Please start again.
如果 Page 1
没有在 Page 2
的 it(...)
中被 visit()
编辑,webapp 似乎缺少一些内部状态。
我知道将所有相关的页面代码部分放入 (describe
-global) function
s 并越来越多地调用它们,这样在每个测试中总是从 Page 1
开始。但是,由于这个应用程序有 33 个不同的功能路径,有 5 到 6 个连续页面(取决于用户在前一页上的输入),我想避免这种代码膨胀、混乱、容易出错和耗时的函数链接——并且全局变量是魔鬼。
更新
从理论到实践,这是功能路径图:
+------ Seite 1 -------+----- Seite 2 -----+------ Seite 3 ------+------ Seite 4 ------+- Seite 5.1 -+- Seite 5.2 -+
| Wohneinheiten | Fördermodell | 1. Wohneinheit | 2. Wohneinheit | Berechnung | Berechnung |
| 2/4 | 8/2 | 12/10 | 6/5 | Input | Output |
| | | | | | |
| Wohneinheiten: | ▼ Modell | Heizwärmebedarf: | | | |
| +- <no> --->(X) | +-▼ Passiv ------>-- HWB: ----------------------------------->-------------> |
| | | | | +- !]0..10] | | | |
| +- WE1: --->(X) | | | +--->(X) | | | |
| | | | | | | | |
| +- WE2: --->(X) | +-▼ Punkte ------>-- HWB: ----------------------------------->-------------> |
| | | | | +- !]10..49] | | | |
| +- WE1: | | | +--->(X) | | | |
| | +- AV-V: -------->--+ | | | | |
| | | | | +-▼ PV ---------------------------------->-------------> |
>--+ | | | +-▼ Solar ------------------------------->-------------> |
| | | +-▼ Niedrig ----->--+-x WRL --------------------------------->-------------> |
| | | | | +- <no> --->(X) | | | |
| +- WE2: | | | | | | |
| | +- AV-V: --->(X) | +-▼ Niedrigst --->--▼ Heizsystem ---------------------------->-------------> |
| | | | | +-▼ Elektrisch | | | |
| | | +-▼ <no> --->(X) | +-▼ PV2kWp | | | |
| | | | | +--->(X) | | | |
| | | | +-o WRL | | | |
| | | | +--->(X) | | | |
| +- WE1: | | | | | |
| +- WE2: | ▼ Modell | Heizwärmebedarf: | Heizwärmebedarf: | | |
| +- AV-V: ----->--+-▼ Passiv ------>-- HWB: ------------->-- HWB: ------------->-------------> |
| | | | +- !]0..10] | +- !]0..10] | | |
+----------------------+ | | +--->(X) | +--->(X) | | |
| | | | | | |
| +-▼ Punkte ------>-- HWB: ------------->-- HWB: ------------->-------------> |
| | | +- !]10..49] | +- !]10..49] | | |
| | | +--->(X) | +--->(X) | | |
| | | | | | |
| +-▼ Niedrig ----->--+-▼ PV ----------->--+-▼ PV ----------->-------------> |
| | | +-▼ Solar ---------> +-▼ Solar --------->-------------> |
| | | +-x WRL -----------> +-x WRL ----------->-------------> |
| | | +- <no> --->(X) | +- <no> --->(X) | | |
| | | | | | |
| +-▼ Niedrigst --->--▼ Heizsystem ------>--▼ Heizsystem ------>-------------> |
| | | +-▼ Elektrisch | +-▼ Elektrisch | | |
| +-▼ <no> --->(X) | +-▼ PV2kWp | +-▼ PV2kWp | | |
| | | +--->(X) | | +--->(X) | | |
| | +-x WRL | +-x WRL | | |
| | +--->(X) | +--->(X) | | |
+-------------------+---------------------+---------------------+-------------+-------------+
Legend:
: ...... Textbox
.. ..... Interval
▼ ...... Dropdown-Listbox or selection
x,o .... Checkbox (checked, unchecked)
<no> ... No input or selection
! ...... Not
(X) .... Error
> ...... Proceed to page or error
现在一切都清楚了,不是吗? (: 好的,它看起来有点绿色,在编辑器中看起来更高更宽。)
在 Seite 1
.
WE2
的情况下,下部的 Seite 3
和 Seite 4
相同且重复
(我不是反对者)
我不确定你的问题到底是什么 -- 你需要提供更多信息:
- 错误来自哪里,是什么触发了它?
- 你确定不拆state/cookies/etc。在测试用例之间?
无论哪种方式,通常您不应该在一个测试用例依赖于前一个测试用例的情况下在测试用例之间共享状态,并且测试用例必须按给定顺序 运行。测试用例(it
)应该相互独立,自给自足。
不遵守此最佳做法会导致难以维护的复杂测试用例。您也无法切换 it.only
来测试单个案例,依此类推。
当您不拥有整个代码库(在团队项目中)时,这一点尤其重要,因为有人可能会更改测试的方式 运行(例如,清除测试之间的状态;随机化测试顺序... ).
我通过我在问题中提到的试图避免的方式解决了这个问题:将相关代码外部化到 describe
-global functions
。这就是我上面提到的所有内容,但至少是 DRY。
describe("Calculation", function() {
let P1withAllInputs = function() {
cy.visit(url)
// ... setting input fields ...
cy.get(next).click()
cy.get('.stg-error-mark').should('have.length', 0)
}
context("Page 1", function() {
// ...
it("With all inputs", function() {
P1withAllInputs()
})
})
context("Page 2", function() {
P1withAllInputs()
// ...
it("No selection", function() {
cy.get(next).click()
cy.get('.stg-error-mark').should('have.length', 2)
})
})
})