明天還會再寫一篇來完結,已經灌水滿30篇了,今年就不寫沒營養的心得囉,
雖然一路寫來文章雖然品質低下,但真的覺得學好多!!
尤其是看ng conf 2019講者的分享時,竟然不會覺得很難
真的要感謝每位Angular Taiwan的講者,尤其是Kevin大大的打底
不過讀書會影片雖然優質,但點閱率大都只有100~200,蠻可惜的~
今天是「Day19_Cypress.io - 優雅的E2E測試」的延申學習
(ng conf 2019)
Avoiding The Suck Of Testing Using Cypress.io | Joe Eames & Jesse Sanders
https://www.youtube.com/watch?v=GH9Dvo_BYkk
原始碼
https://github.com/jessesanders/ngdoc
簡介:
超棒的內容!!!
Snapshot at a moment in time
Edge cases
Cryptic errors/stack traces
No dev tools during tests
安裝Cypress
npm install cypress --save-dev
# or 使用schematic建新專案
# 會幫你移除angular內建的protractor
ng new @briebug/cypress-schematic
npx cypress open
# 就會去跑 CY global object,幾乎都是靠這個大物件在跑cypress
# 測試畫面非常的友善
cypress.json 設定要測的網站
{
"baseUrl": "http://localhost:4200"
}
寫整合測試,測試案例
ngdoc/cypress/integration/articles.spec.ts
describe('Articles', () => {
beforeEach(() => {
cy.visit('/'); // 一開始去讀網頁
});
it('should load when home page loads', () => {
cy.get('app-article').should('have.length.greaterThan', 0);
});
it('should search', () => {
// 支援各種selector
cy.get('input.search').type('canvas');
cy.get('.search-button').click();
cy.get('app-article').should('have.length', 1);
});
// USER CREATED TEST
// RUN APP WITH 'NPM START'
// IN A DIFFERENT CONSOLE WINDOW RUN CYPRESS WITH 'NPX CYPRESS OPEN'
it('should search (student version)', () => {
// put test here
});
// 後面2個測試案例是讓你練習的,
// 答案寫在answers/articles.answers.spec.ts
// USER CREATED TEST FOR TAGS
it('should filter tags', () => {
// check that the total number of tags is 20 (tag有20個00)
// find tags search input and type 'anim' in it
// assert the number of tags returned
// click on 2nd tag 'animations'
// assert the number of selected tags is 1
// assert total tags is 15
// click on the tag with routing
// assert there are 3 articles
// BONUS
// reset filters, check number of tags and articles
// select a tag, assert it's selected
// unselect that tag, assert back to default state
});
});
"types":[
"cypress"
],
像這樣
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"module": "es2015",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"types":[
"cypress"
],
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
]
}
}
articles-using-waits.spec.ts
describe('Articles using waits', () => {
it('should wait for tags', () => {
cy.server();
cy.route('/api/tags').as('tags'); // alias:string 取別名
cy.visit('/');
cy.wait('@tags'); // @symbol
cy.get('.tags-container input').type('anim');
cy.get('div.tags').should('have.length', 3);
});
// USER CREATED TEST FOR WAITS
// should wait for articles to load then assert count
// BIG HINT: route: api/articles/recent
// More subtle hint: route: api/articles/recent
// BONUS - assert the title of the 3rd article
// BONUS - assert anchor target for articles is _blank
// HINT: http://example.cypress.io
// HINT: https://docs.cypress.io/api/commands/should.html#Value
it('recents articles should display 25 articles', () => {
cy.server();
cy.route('/api/articles/recent').as('articles');
cy.visit('/');
cy.wait('@articles');
});
});
cy.server(); // start the server
cy.route({
method: "GET", // Route all GET requests
url: "/users/*", // that have a URL that matches '/users/*'
response:[] // and force the response to be: []
});
// 可以攔截matches的後端路由,並強制回傳[]
articles-using-stubs.spec.ts
// USER CREATED TEST FOR STUBS
// stub the tags api call to only return 'constructor' & 'components'
// assert that tags count = 2
// HINT tag model: {_id: '1', tag:'testing'}
// BONUS: select a tag by clicking on it and
// have api / articles / search return 1 article
it('should display 2 tags', () => {
cy.server();
// 攔截/api/tags,並回傳我們想塞的資料 [ {_id:...},{...} ]
cy.route("/api/tags",[
{ _id: "1", tag: "constructor" },
{ _id: "2", tag: "components" }
]).as('tags');
cy.visit('/');
cy.wait('@tags');
});
npx cypress run
# 還把測試結果錄成mp4,超棒的
# 如果測試失敗,還會有截圖