Open48

はじめてのCypress

kzk4043kzk4043

Opening the App

npx cypress open
または
npm run cypress:open // "cypress:open": "cypress open"をpackage.jsonに登録

the Cypress Launchpad will open.

Cypress Launchpadってなに。

ふむ…独自のアプリが立ち上がっている。Component testingもあるのね。
configファイルがいっぱい…設定めんどそう…

  • cypress.config.js:メインの設定ファイル?
  • cypress/support/e2e.js:テストの前にロードされるサポートファイル?
  • cypress/support/commands.js:コマンドいじる用?
  • cypress/fixtures/example.json:fixturesってなんやろ…

https://docs.cypress.io/guides/references/configuration

詳しくはこちららしい。もうちょっと進んでから見る。

kzk4043kzk4043
  1. npm run cypress:openでCypress Launchpadが立ち上がる
  2. そこでブラウザ選ぶとそのブラウザが立ち上がる→ここでテストされる

って感じか

kzk4043kzk4043

Writing Your First E2E Test

Start E2E Testing in Chromeを押したら勝手に開いた。

specs/runsってなんだろう。
なんか周辺アプリ?が充実してるんやな…

kzk4043kzk4043

書き方はJestかと思ったら、

What are describe, it, and expect ?
All of these functions come from Bundled Libraries that Cypress bakes in.
describe and it come from Mocha
expect comes from Chai

kzk4043kzk4043
cy.visit('https://example.cypress.io') // 対象URLに遷移
cy.contains('type').click() // typeという文字を含む要素をクリック?
cy.url().should('include', '/commands/actions') // urlで今いるページのURLを取得して、shouldでアサーション

便利そうな雰囲気

We can use cy.get() to select an element based on its class. Then we can use the .type() command to enter text into the selected input.

kzk4043kzk4043

本来はgetする時はクラスですべきではないらしい

https://docs.cypress.io/guides/references/best-practices#Selecting-Elements

Best Practice: Use data-* attributes to provide context to your selectors and isolate them from CSS or JS changes.

data-* を使えとのこと。テストのために本体をいじるのかー…これ結構だるくないか…?そういうもん?まあなんか安定しそうな感じは確かにあるが…

// cypress/support/commands.ts

Cypress.Commands.add('getBySel', (selector, ...args) => {
  return cy.get(`[data-test=${selector}]`, ...args)
})

Cypress.Commands.add('getBySelLike', (selector, ...args) => {
  return cy.get(`[data-test*=${selector}]`, ...args)
})

便利なカスタムコマンド

kzk4043kzk4043

https://docs.cypress.io/guides/references/cypress-studio

cypress studioってやつでテストを実際にやって記録できるっぽい。スプシのマクロを記録的な。
こういうのって微妙にバグったりするイメージあるけどどうなんやろ。
それとコードに落としてくれるのか、それとも編集不可な形式で生成されるのか。

kzk4043kzk4043

Next steps
Take our free Testing your first application course.
Learn more about the Cypress App UI.
Start testing your app.
Set up intelligent code completion for Cypress commands and assertions.
Record your test results to Cypress Cloud for advanced features like parallelization, flake detection, and more.
Check out the Real World App (RWA) for practical demonstrations of Cypress testing practices, configuration, and strategies in a real-world project.
Search Cypress's documentation to quickly find what you need.

kzk4043kzk4043

https://learn.cypress.io/testing-your-first-application

チュートリアル?流し見する
あーチュートリアル用のリポジトリを用意してくれてる感じか。まあいいか、流すだけにしよう。

ちょっと丁寧すぎて冗長な感じもあるな…

YOU WILL LEARN

How to install Cypress
How to write Cypress E2E tests
How to create custom Cypress commands

  • App Install and Overview
  • Installing Cypress and writing your first test
  • How to test forms and custom Cypress commands
  • How to test multiple pages
  • How to test user journeys
kzk4043kzk4043

Now that we have two tests, each time we save our file, Cypress is going to re-run all of the tests in this file. This is ok when you only have a few tests, but what if we had dozens of tests in this single spec file? Each time we saved we would have to wait until Cypress finished running all of our tests. This is not ideal especially when we are really only concerned with the current test we are writing.
We can tell Cypress to only run a specific test by using it.only() like so:

it.onlyはこういう使い方なのね

kzk4043kzk4043

API

  • visit
  • get
    • cy.get("dt").eq(0).contains("4 courses")
    • cy.get("[data-test='hero-heading']").contains("Testing Next.js Applications with Cypress")
  • eq
    • cy.get("dt").eq(0).contains("4 Courses")
    • ああ、これってgetで取ってきた配列の何番目を取るかってこと?アサーションじゃないのね…
  • contains
    • cy.get("dt").eq(1).contains("25+ Lessons")
  • should
    • cy.getByData("success-message").should("exist")
    • これはなんだ…?→Docs
    • disabledになってるかとか、フォーカス当たってるかとか、その要素がどういう状態にあるべきかを結構柔軟にチェックできそう?
  • find
    • cy.getByData("course-0").find("a").contains("Get started").click()
    • getと何が違う?→参考
      • cy.get('.sidebar').get('.menu-item').click();だと.menu-itemは全体から探している(これだと最初のgetが無意味になっている?)が、cy.get('.sidebar').find('.menu-item').click();なら.sidebarの中の.menu-itemを探している

基本getしてきてからeqとかでチェインしてアサートか

フォーム系

beforeEachもある

kzk4043kzk4043

To do this, we can write our own custom Cypress command. What a custom command allows us to do is to reuse code or functionality across all of our Cypress spec files.

custom Cypress commandなる概念がでてきた

cypress/support/commands.ts
declare namespace Cypress {
  interface Chainable {
    getByData(dataTestAttribute: string): Chainable<JQuery<HTMLElement>>
  }
}

Cypress.Commands.add("getByData", (selector) => {
  return cy.get(`[data-test=${selector}]`)
})

あー前もでてきたやつ

cy.getByData("hero-heading") // こう書くだけで

cy.get("[data-test='hero-heading']") // これと同等になる
kzk4043kzk4043

https://learn.cypress.io

チュートリアルサイトになってるのか。
テストの基礎とかもある。よさそう

  1. Testing Your First Application
  2. Testing Foundations
  3. Cypress Fundamentals
  4. Advanced Cypress Testing Concepts

今のは1

kzk4043kzk4043

https://learn.cypress.io/testing-foundations/testing-is-a-mindset

YOU WILL LEARN

Learn what to test and why
Arrange, Act, Assert
The Difference between Unit, Integration and E2E tests

  • Testing is a Mindset
  • Identifying What to Test
  • Manual vs Automated Testing
  • Who should be responsible for testing?
  • The Testing Pyramid
kzk4043kzk4043

Understanding the Testing Mindset

gpt
要点
•   ​テストはマインドセット​:
    •   テスト方法論やツールよりも、テストはまずマインドセットであることを理解することが重要。
•   ​異なる視点​:
    •   ソフトウェア開発チームとQAチームが分かれているのは、アプリケーションを全く異なる視点で見るから。開発者は作ることに責任があり、QAは壊すことに責任がある。
•   ​QA的な思考​:
    •   開発者がテストを書くためには、QA的な考え方を学び、それを自動化テストに反映する必要がある。
•   ​継続的なテスト思考​:
    •   新しい機能リクエストやバグ修正の際、まず関連するアプリケーションコードのテスト方法を考える。
    •   これらの議論は、開発チームとQAチームの両方を含めて行うべき。QAが手動テストのみを行っていたとしても、彼らの意見は非常に価値がある。
•   ​QAチームがいない場合​:
    •   専任のQAチームがいない場合、開発チームで新機能が正しく動作するためのテストの種類について議論する必要がある。
    •   目標を設定し、バックワードに考え、それを小さなステップに分けてテストに変換することで、明確な道筋と適切なテストスイートを持つことができる。
•   ​Agile開発におけるテストケースの定義​:
    •   アジャイル開発を行っている場合、テストケースはユーザーストーリーの受け入れ基準として定義される。
kzk4043kzk4043

Identifying What to Test

gpt
● ​テスト対象の特定​:
•  テストを書く際に、何をテストすべきか理解するのは難しい。特に既存の大規模なアプリケーションの場合、最初にどの部分をテストするか判断することが重要。
•  ミッションクリティカルな部分(ログイン/認証、商品購入、クレジットカード処理、サインアップフォームなど)が最優先で、エンドツーエンドのテストを行うべき。
● ​ユーザージャーニー​:
•  ユーザージャーニー(アプリケーションの主要なユーザーパス)に沿ってテストを書くことが推奨される。
•  例として、eコマースアプリケーションでは「商品検索→カートに追加→配送情報入力→支払い情報入力→購入完了」というユーザージャーニー全体を単一のテストでカバーする。
● ​新機能​:
•  新しい機能をテストする際、最終目標を念頭に置き、機能を小さなステップに分解してテストを書く。
•  各ステップのテストを設け、そのテストが通るようにコードを書いていくことで、リファクタリング時にも自信を持って作業できる。
● ​バグ​:
•  アプリケーションでバグが発生したら、そのバグに対してまず失敗するテストを書き、それからバグを修正。その後、テストが通ればバグがなくなったことを確認できる。
•  この方法で、同じバグが再度現れるのを防ぐことができる。

ミッションクリティカルな部分(ログイン/認証、商品購入、クレジットカード処理、サインアップフォームなど)が最優先で、エンドツーエンドのテストを行うべき。

kzk4043kzk4043

Manual vs Automated Testing

gpt
● ​手動テスト​:
•  手動テストとは、通常QAがアプリケーションと物理的にやり取りすることを指し、時間がかかる。
•  手動テストだけでプロダクションへコードを毎日何度もデプロイするのはほぼ不可能。
●  ​自動化テスト​:
•  CI(継続的インテグレーション)とCD(継続的デプロイ)の進展により、テストを含むあらゆる作業の自動化が進んでいる。
•  CI/CDを活用するチームにとって、自動化テストはスケールするために不可欠。
●  ​シフトレフト​:
•  テストの責任が開発者にも増え、開発プロセス全体に統合される動き。
•  開発プロセスの終盤でのテストではなく、最初からテストを考慮して行うアプローチ。
●  ​自動化テストの普及​:
•  自動化テストはソフトウェア開発チームで標準になりつつあり、その有用性は今後さらに増大。
•  自動化テストの経験がない場合でも、Cypressを使った「Real World Testing」で学ぶ支援が可能。

What is Shifting Left Testing?

it means that developers are being incorporated into the testing cycle earlier than ever before. This movement in the testing world is commonly known as “shifting left”.

kzk4043kzk4043

Who should be responsible for testing?

gpt
•  ​テストは全員の責任​:
•  テストは最終的に全員の責任であり、信頼性の高いソフトウェアを配信するためには、チーム全体の思考プロセスに組み込むべき。
•  ​3つの典型的なチーム構成​:
1._専任の開発チームとQAチーム_<!---->
•  専任の開発チームはソフトウェア開発を担当し、QAチームはテストを担当する構成。
2._デザイナー、開発者、QAなどの小規模チーム_<!---->
•  デザイナー、開発者、QAエンジニアなどが一緒に働く小さなチームで、開発者がコードを担当し、QAがテストを担当。
3._フルスタックのソロ開発者_<!---->
•  初期段階のスタートアップなどでは専任のQAチームがなく、すべてのテスト責任を開発者が負う。
•  ​全員の責任​:
•  専任のQAエンジニアがいる場合でも、アプリケーションが意図した通りに動作することを確認するのは全員の責任。
kzk4043kzk4043

What is the Testing Pyramid?

gpt
● ​テストピラミッドの概要​:
•   テストピラミッドは、さまざまなテストの種類とそれらの関係を図示したもの。
•   テストの定義やラベルは重要だが、最も重要なのはテストが何をするか。
● ​ユニットテスト​:
•   ピラミッドの基盤に位置し、最も多くのテストを書く部分。
•   単一の「ユニット」をテストし、他のシステム部分に依存しない。
•   関数に特定の入力を与えた場合に特定の出力が得られるかをテスト。
● ​統合テスト​:
•   アプリケーション内の個別の部品が期待通りに動作するかを確認。
•   ユニットテストとは異なり、依存関係があり、システム内の複数の部分が正しく連携するかをテスト。
● ​コンポーネントテスト​:
•   モダンなフロントエンドライブラリで使用されるコンポーネントをテスト。
•   コンポーネントを独立してテストし、ユニットテストや統合テストと類似している。
•   セットアップが容易で迅速に実行でき、複雑なUIをテストするのに適している。
● ​エンドツーエンド(E2E)テスト​:
•   ブラウザで動作するすべてをテストし、リアルユーザーの動作を模倣。
•   例として、新しいアカウントの登録、ログイン、商品購入、ログアウトを行う単一のテスト。
•   統合テストと同様の内容をテストするが、ユーザーの実際の操作を検証するため、さらに価値が高い。
kzk4043kzk4043

https://learn.cypress.io/cypress-fundamentals/how-to-write-a-test

YOU WILL LEARN

How to use Aliases
How to chain methods and assertions together
How Cypress works 'under the hood'

  • How to Write a Test
  • Cypress Runs Tests in the Browser
  • Command Chaining
  • The Asynchronous Nature of Cypress
  • Waiting and Retry-ability
  • How to Debug Failing Tests
  • Cypress is just JavaScript
kzk4043kzk4043

How to Write a Test

gpt
•   ​テストの構成​:
    •   テストはAAAパターン(Arrange-Act-Assert)に基づいて記述することで、読みやすく、拡張しやすくなる。
•   ​Arrange(準備)​:
    •   テストのセットアップを行う。例: Cypressを使ってブラウザを開き、正しいURLにナビゲートする。
    
    cy.visit("http://localhost:8888")
    
•   ​Act(実行)​:
    •   何らかのアクションを実行する。例: todoアプリで「Buy Milk」というタスクを追加する。
    
    cy.get(".new-todo").type("Buy Milk{enter}")
    
•   ​Assert(確認)​:
    •   アクションの結果が期待通りであることを確認する。例: 追加されたtodoアイテムが1つであることを確認する。
    
    cy.get(".todo-list li").should("have.length", 1)
    
•   ​全体の例​:
    •   実際のテストファイルは以下のようになる。
    
    // app.spec.js
    describe("React TodoMVC", () => {
      it("adds a single todo", () => {
        cy.visit("http://localhost:8888") // Arrange
        cy.get(".new-todo").type("Buy Milk{enter}") // Act
        cy.get(".todo-list li").should("have.length", 1) // Assert
      })
    })
    
•   ​フレームワーク​:
    •   CypressはMochaをベースにしている。
    •   各テストファイルは通常`describe()`関数から始まり、テストを整理するために使用される。
    •   itブロック内に実際のテストコードが記述される。
•   ​各ステップの詳細​:
    •   ​Arrange​: Cypressに指定のURLを訪問させる。
    •   ​Act​: 特定のクラスの要素を取得し、文字を入力してEnterキーを押す。
    •   ​Assert​: アプリに追加されたtodoが1つだけであることを確認する。
これにより、Cypressを使ったE2Eテストの基本的な構成と実行方法が理解できます。
kzk4043kzk4043

Cypress runs in the browser

gpt
•   Cypressはブラウザ内で実行される:
    •   他の多くのテストツールとは違い、Cypressはブラウザ内でテストを実行する。
•   アプリケーションと同じ環境でテストが実行されるため:
    •   ブラウザが発する全てのイベントを検出し、テスト内の全ての要素にネイティブアクセスができる。
    •   これは、アプリケーションと同じ環境でテストが実行されるためである。
•   他のテストツール(例:Selenium)は:
    •   ブラウザの外部で実行され、リモートコマンドをネットワーク経由で実行してブラウザを操作する。
    •   Cypressはこれとは完全に逆である。
•   ブラウザ内で実行されるため、Cypressはリアルタイムで:
    •   Webトラフィックの読み取りや変更が可能。
    •   ウィンドウオブジェクト、ドキュメント、DOM要素、サービスワーカーなどにもネイティブアクセスが可能。
    •   例えば、ReduxやMobXといったフロントエンドの状態管理ライブラリをテスト内で設定・変更することができる。
•   どんなものでもブラウザがアクセスできるものには、Cypressもアクセス可能。
•   ただし、これはトレードオフを伴う場合がある。

Trade-offs

kzk4043kzk4043

Command Chaining

gpt
•   ​Cypressのコマンドチェーンの仕組み​:
•   Cypressはコマンドをチェーンする際にPromiseチェーンを管理し、各コマンドが次のコマンドに対して「サブジェクト」を渡す。
•   チェーンが終了するかエラーになるまでこのプロセスは続く。
•   開発者は通常Promiseを直接使う必要はないが、その動作を理解しておくと役立つ。
コマンドチェーンの例
•   ​コマンドチェーンのサンプル​:
•   例: cy.get(".todo-list li").find("label").should("contain", "Buy Milk")
•   cy.get()が`<li>要素をfind()`に渡し、`find()``<label>`要素を検索する。
•   最後に`should("contain", "Buy Milk")``<label>`要素が"Buy Milk"を含むことをアサートする。
注意点
•   ​全てのCypressコマンドがチェーン可能なサブジェクトを返すわけではない​:
•   例: cy.clearCookies()はnullを返すため、チェーンできない。
•   cy.get()や`cy.contains()`のようなコマンドは、チェーン可能なDOM要素を返す。
直接操作する場合
•   ​Cypressコマンドから直接サブジェクトを操作したい時​:
•   サブジェクトを`.then()`に渡す必要がある。
•   .then()や`cy.wrap()`については、Cypressの非同期性に関するレッスンで詳しく説明している。
•   詳細な情報はhttp://learn.cypress.io|Cypressのドキュメントで確認可能。
kzk4043kzk4043

Understanding the Asynchronous nature of Cypress

この章大事そう

gpt
•   ​Cypressの非同期性の理解​:
    •   Cypressの非同期性の理解は非常に重要。
    •   非同期性を理解せずにテストをデバッグすると問題や混乱が生じる可能性がある。
•   ​Return vs. Yield​:
    •   Cypressコマンドはサブジェクトを返さない:
        •   例: const button = cy.get("button"); button.click() は動作しない。
        •   代わりに、Cypressコマンドはサブジェクトを「イールド」する。
    •   変数の使用は推奨されない。
•   ​コマンドはキューに追加され、後で実行される​:
    •   コマンドの間に多くのCypressコードが実行され、すべてが正しく行われるようにする。
•   ​.then()の使用​:
    •   サブジェクトを直接操作するには、`.then()`を使用:
        •   .then()はJavaScriptのPromiseに似ているが、Cypressコマンドの一部。
        •   純粋なPromiseではないため、`async`/awaitは使用できない。
    •   コールバック関数から返されたものが新しいサブジェクトとなる(`undefined`を除く)。
•   ​.wrap()の使用​:
    •   jQueryオブジェクトをCypressコマンドで操作するには、`cy.wrap()`を使用。
    •   例:
        
        cy.get("button").then(($btn) => {
          const cls = $btn.attr("class");
          cy.wrap($btn).click().should("not.have.class", cls);
        });
        
    •   cy.wrap()を使うことで、Cypressが適切なコンテキストで操作を実行できるようにする。

• .then()はJavaScriptのPromiseに似ているが、Cypressコマンドの一部。
• 純粋なPromiseではないため、async/awaitは使用できない。

thenってPromiseじゃないの…ややこい。

必要になったら読む。
Commands Are Asynchronous
The Cypress Command Queue
Return Values

kzk4043kzk4043

Waiting & Retry-ability

gpt
•  ​​リトライ性とフレーク耐性​​:
•  Cypressのリトライ性は重要な機能であり、理解が必要。
•  他のテストツールは指定時間待機が必要だが、Cypressは自動で待機。
•  Cypressはブラウザ内で動作し、アプリケーション内の全てのイベントを理解できる。
•  ページのロード/アンロード、イベントの発生を認識。
•  アニメーションが終わるまで、要素が表示されるまで、他の要素に覆われなくなるまで自動で待機。
•  ページ遷移時も、新たなページが完全にロードされるまでコマンドの実行を一時停止。
•  ​​エイリアス(Alias)の使用​​:
•  エイリアスを使って要素、リクエスト、インターセプトの参照をテスト中に行う。
•  .as() 関数を使ってエイリアスを作成。
cy.get("table").find("tr").as("rows")
•  作成したエイリアスを`cy.get()`で参照。
cy.get("@rows")
•  ​​明示的な待機​​:
•  自動待機に加え、特定の待機が必要な場合もある。
•  ネットワークリクエストの完了を待つなど。
•  エイリアスを使った待機が最適。
beforeEach(() => {
   cy.request("POST", "/users").as("signup")
})
it("should allow a visitor to sign-up, login, and logout", () => {
   cy.visit("/")
   cy.wait("@signup")
})
•  POSTリクエストのエイリアスを作成し、テスト内でそのエイリアスの完了を待機。

requestがPromise返せればawaitで待てばいいのでは…?

kzk4043kzk4043

How to Debug Failing Tests

gpt
失敗するテストのデバッグ方法
•  ​​Cypress UI​​:
•  最速で問題を見つける方法の一つ。
•  エラーが発生する前のステップを確認可能。
•  ステップをクリックすると、ブラウザのコンソールに有用な情報が出力される。

•  ​​スクリーンショットとビデオ​​:
•  cypress run コマンドでヘッドレスモードを使用すると、自動でスクリーンショットとビデオが記録される。
•  失敗点のスクリーンショットとテストのビデオが提供されるため、CI環境で特に有用。
•  手動で`cy.screenshot()`コマンドを使用してスクリーンショットを撮ることも可能。

•  ​​ログの使用​​:
•  cy.log() と console.log() を使って情報をログとして出力可能。
•  cy.log() はCypressのコマンドログにメッセージを表示。
•  console.log() はブラウザのコンソールにログを表示。
console.log("my custom message")
•  ​​ブラウザの開発者ツール​​:
•  ブラウザ内でCypressが動作するため、開発者ツールをフルに活用可能。
•  アプリケーションコードのデバッグ時と同様の技法を使ってテストのデバッグが可能。
テストが失敗する際はこれらの方法を駆使して問題を特定し、修正することが重要です。

CypressUIはたぶんステップバイステップで状態が見れるやつのことかな

kzk4043kzk4043

https://learn.cypress.io/advanced-cypress-concepts/database-initialization-and-seeding

YOU WILL LEARN

How to debug test failures
Database initialization and seeding
How to test network requests

  • Database Initialization and Seeding
  • Running in Continuous Integration (CI)
  • Intercepting HTTP Requests
  • API and Integration Tests
  • Building Custom Commands
  • Viewport and Browser Testing
  • Cypress Methods You Need to Know
  • Using Data for Dynamic Tests
kzk4043kzk4043

Database Initialization & Seeding

gpt
•   データ戦略の重要性
    •   テストにどのデータが必要か、どう取り扱うかを考える戦略が必要
    •   バックエンドとテストユーザーの有無
    •   リアルタイムでテストユーザーを作成する必要性
    •   システム/アプリのエンティティ間の関係
    •   データベースの種まきや初期化を他チームが管理しているかどうか
•   データの準備方法
    •   UIを使って必要なデータを作成する
        •   簡単で直感的
        •   時間がかかり、テスト間の依存性問題
    •   SQLクエリでデータを直接作成
        •   信頼性が高いが、データモデル変更時のメンテナンスが必要
    •   API呼び出しでデータを準備
        •   バックエンドにデータ管理の責任を負わせる
        •   公開エンドポイントのセキュリティ対策が必要
    •   データベースのダンプやインポート
        •   実データの利用可能性
        •   セットアップと展開が複雑になる可能性
    •   カスタムスクリプト(ファクトリー)でテストデータを生成
        •   完全なデータ制御
        •   スクリプトのメンテナンスに時間がかかる
•   テストデータ生成のためのスクリプト例 (Faker.jsを使用した例)
    •   ダミーデータを生成し、JSONファイルに書き出すスクリプト
import path from "path"
import fs from "fs"
import shortid from "shortid"
import faker from "faker"
import bcrypt from "bcryptjs"
import { times } from "lodash"

const passwordHash = bcrypt.hashSync("s3cret", 10)

const createFakeUser = () => ({
  id: shortid(),
  firstName: faker.name.firstName(),
  lastName: faker.name.lastName(),
  username: faker.internet.userName(),
  password: passwordHash,
  email: faker.internet.email(),
  createdAt: faker.date.past(),
  modifiedAt: faker.date.recent(),
})

export const createSeedUsers = (numberOfUsers) =>
  times(numberOfUsers, () => createFakeUser())

export const saveUsersSeed = (numberOfUsers) => {
  const seedUsers = createSeedUsers(numberOfUsers)
  fs.writeFile(path.join(process.cwd(), "seedUsers.json"), for seedUsers)
}
このスクリプトは、ダミーユーザーを生成し、それらをJSONファイルに書き出すプロセスを示しています。このデータは、テストフィクスチャとして使用したり、テストデータベースへ書き込むために使用できます。
kzk4043kzk4043

Intercepting Network Requests

gpt
•   ​ネットワークリクエストのインターセプトの重要性
    •   Webアプリケーションのテストにおいて、ネットワークリクエストとレスポンスを操作・テストする方法を知ることは極めて重要
•   ​基本的なインターセプト方法
    •   cy.intercept("POST", "/users")で、`/users`ルートへのすべてのPOSTリクエストをインターセプトする
    •   インターセプトしたリクエストにエイリアスを付けることが多い
        
        cy.intercept("POST", "/users").as("signup")
        cy.wait("@signup")
        
•   ​既存のインターセプトの上書き
    •   既存のインターセプトを上書きし、フィクスチャを使ってレスポンスデータをモックできる
    •   beforeEach()内でインターセプトを設定し、毎回のテストの前に実行されるようにする
        
        beforeEach(() => {
          cy.intercept("GET", "/transactions/public*").as("publicTransactions")
        })

        cy.intercept("GET", "/transactions/public*", {
          fixture: "public-transactions.json",
        }).as("mockedPublicTransactions")
        
•   ​ヘッダの変更
    •   レスポンスからのヘッダを変更可能
        
        cy.intercept("GET", "/transactions/public*", {
          headers: {
            "X-Powered-By": "Express",
            Date: new Date().toString(),
          },
        })
        
•   ​レスポンスデータの変更
    •   レスポンスデータの一部を変更する方法
        
        cy.intercept("POST", "/bankaccounts", (req) => {
          req.continue((res) => {
            res.body.data.listBankAccount = []
          })
        })
        
•   ​リクエストの検査
    •   インターセプトを使ってリクエスト内容を検査
        
        cy.intercept("POST", apiGraphQL, (req) => {
          if (req.body.operationName === "CreateBankAccount") {
            req.alias = "gqlCreateBankAccountMutation"
          }
        })

MSWとの連携とかどうなるんだろ。なんかasとwaitの組み合わせイケてない感

kzk4043kzk4043

API & Integration Tests

APIから帰って来るデータとかのチェックができる

kzk4043kzk4043

Building Cypress Commands

Cypress.Commands.add("getBySel", (selector, ...args) => {
  return cy.get(`[data-test=${selector}]`, ...args)
})

Viewport and Browser Testing Tips

ブラウザおよびViewportの指定可能

kzk4043kzk4043

Cypress Methods You Need to Know

  • its()
  • invoke()
    • Cypressはjsだといいつつ普通にjsメソッドは使えない…?
  • request()
  • whithin()
kzk4043kzk4043

Using Data to Build Dynamic Tests

• ​​データ駆動テストとは
• データ駆動テストとは、変数、フィクスチャ、またはデータベースからのデータを使用してテストの全ての側面を構築すること

kzk4043kzk4043

ちょっと一回react-tutorialでテスト書いてみる

kzk4043kzk4043

なんかエラーはきながら無限ループしだした…

(uncaught exception)TypeError: Cannot read properties of null (reading 'document')

これとりあえず止めるとかできないのか…?

kzk4043kzk4043

おお、左側のコマンド履歴にホバーするだけで、その時点でどれが選択されてるかみたいなのが反映される。すご

kzk4043kzk4043

Cypress Studio

Cypress Studio provides a visual way to generate tests within Cypress, by recording interactions against the application under test.
You can also generate assertions by right clicking on an element that you would like to assert on.

アサーションも右クリックで追加できる。

制限

  • コンポテストでは使えない
  • 複数オリジンを使用するテストには使えない(どういうこと…?)

設定

experimentalStudio: trueをconfigに追加

cypress.config.js
{
  e2e: {
    experimentalStudio: true
  }
}
kzk4043kzk4043

The Cypress Real World App (RWA) is an open source project implementing a payment application to demonstrate real-world usage of Cypress

…?

https://blog.morifuji-is.ninja/post/2021-07-13/

このwebアプリケーション自体は銀行口座管理ツールなんですが、この中にはCypressの使い方やベストプラクティスなどを盛り込んだCypressの動作デモも含まれており、それを公開することで広くCypressの使い方・ベストプラクティスを知ってもらおうという目的らしいです。

なるほど、ちゃんと作ったサンプルってことね。

kzk4043kzk4043

手順

  1. Cypressを起動して、e2eテストを選ぶ
  2. 何かしら作っておいたテストを実行する
    3. そのテストの実行後からコマンドを追加できる。途中の時点から修正できないのかなと思ったけどできなさそう?
  3. 実行後のテスト名の右にある「Add Commands to Test」を押すとCypress Studio起動
  4. そのままクリックとかInputすればOK。右クリックでアサーション追加可能

空のテストとか用意しなきゃいけないのはちょっとめんどいけど、(→descrive単位の右に「Add New Test」があった)どっちかというと既存のテストにちょっと修正加えるみたいな用途を想定してるんかな?