既存の角度プロジェクトへのサイプレスの追加


(もともと私のブログでは2021年12月23日)
私がAngular 13シングルページアプリケーション(SPA)で仕事を始めたとき、私は最初にエンドツーエンドテストのためにセレンをセットアップすると考えました、しかし、急な学習曲線のために、私は一般的にスタックで経験していましたwindow.external ライブ環境のプロパティ、私はそれを延期し続けた.
しかし、私はこのプロジェクトのために書かれたテストが実際には、実行時にテンプレートがアクセスされたときにページがロードされなかった依存性エラーをキャッチしない状況に遭遇しました.私は、これが私が使用していないからであると思いますTestBed テストベッドの大部分のために、テストベッドは高いオーバーヘッドを持っていて、劇的に私の2 , 000のテストケースを減速させます.
私も最近記事を読みましたFrom Zero to Tests 私はテスト構造を再考してくれました.私のテストのほとんどは現在、単体テストであり、いくつかの統合テストであるかもしれません.ほとんどの場合、この関数は、我々が期待している入力を与えられたときに期待することを行います.私は間違いなくDOMレンダリングに対処するテストを持っていません.それで、私はダウンタイムのストレッチを持っていました.私は特定のプロジェクトを待っている人はいません.

Why Cypress?
You may have noticed that I mentioned Selenium to begin with, but this article is about Cypress. Going back to Corgibytes, this time to Integration Tests Can Be Fun!, I didn't really care for the idea of setting up a black box that was hard to understand to handle my higher level tests. Plus, I've heard good things about Cypress from other sources, and it looks like it is relatively easy to set up, compared to Selenium.


始める


サイプレスをセットアップすることに決めた最初のことはtheir website そして、見始めてください.この動画にはまだ動画レスポンスがありませんnpm install -D cypress . 私は、これがうまくいくと確信します、しかし、私は角がそれ自身のパッケージ追加プロセスを持っていることを知っています、そして、確かに、角の特定のインストール経路のために二重にチェックしてくださいEnd-to-End testing with Cypress - Testing Angular , これは角度CLIコマンドng add @cypress/schematic 代わりに.

NOTE:
If, like me, the first thing you do after installing Cypress is run it with npm run cypress:open, you may be confused by the immediate error message of "Warning: Cypress could not verify that this server is running." Don't worry about this for now if you're following the tutorials. Later in, they go over running your development server alongside Cypress for testing.


そこから私はintroductory tutorials that Cypress provides 始める.これはブラウザオートメーションのスイートとの私の最初の経験です、そして、私は言わなければなりません、テキストでコマンドを入力するのはかなり楽しいです、ブラウザーウインドウに戻ってホップして、それを実行するのを見てください!確かに前方にプッシュし、私は実際のアプリケーションをテストすることができる状態になる興奮.
それで、次のステップは、サイプレスが実際にそれに対してテストすることができることを保証することでした.cypressのチュートリアルでは、ユーザーをlocalhostアドレスを入力するように指示しますcy.visit() , しかし、角CLIng add 以前に使用したコマンドは、すでにCypressのチュートリアルで述べたものとは異なるデフォルトのlocalhostアドレスを設定しました.を返します.ng serve . カスタマイズした場合ng serve , 私は、これが真実であるかどうか知りません、しかし、私のケースではサイプレスが探していたアドレスはマッチです.( localhostアドレスをカスタマイズしたい場合は、以下のように設定しますStep 3 of Testing Your App .)
角度も2、3の基本的なテストファイルを提供しますcontains() 使用するアサーションng add プロジェクトにサイプレスを含める.私の場合では、これは実際の内容で既存のプロジェクトであるので、どちらも渡されませんでした.私は、彼らが新しいアプリケーションを作成するとき、角のCLIが生成する空の新しいアプリのために有効であるかどうかわからないですたぶんそうだろう.
私のケースは、ユーザーが実際にこのページを決して見てはならないという点で少し珍しいですユーザーがアクセスするURLによって個々のページにアクセスするソフトウェアは、彼らが表示されます.ユーザーがアプリケーションのルートで終了する唯一の時間は、どうにか、ソフトウェアの格納されたリンクがどんな有効なルートにもマッチしなかったならば、あります.それにもかかわらず、ページが読み込まれ、レンダリングされることを確認するのに便利です.私は、私が概念の証明のために私のアプリケーションのルートで持っている最小限の内容とリンクに対して、いくつかの基本的なテストケースを書くだけで終わりました.
私はまた、ユーザーの1つはかなり簡単だったページに直面し、その概念の証明としても、そのための初期状態のテストを行った.追加data-cy="whatever" 重要な要素にタグを付け、サイロードにページロードに存在するものをチェックしてくださいそして、ページロードで隠されなければならないものはそうです.

模擬環境の設定


この段階のほとんどの開発者は、ログインフローをテストし始め、サーバーの要求のためにスタブを構築しています.しかし、私のアプリケーションでは、ページがロードされるソフトウェアは、すべてを処理していますが、私のコードはユーザを認証することとは関係ありません.そこで私が次に何をしなければならなかったのかwindow.external ページが生産環境にあるとき.

うまくいかなかった


最初に私はカスタムコマンドの機能を使用して私は私のユニットテストのために使用してきた模擬を適用するコマンドを追加しようとすることを決めたwindow.external . TypesScriptを含む即座のハードルがあり、コマンドファイルを解析していましたcommands.ts そして、それは私のカスタムコマンドの名前に適応Argument of type 'mockWindow' is not assignable to parameter of type 'keyof Chainable<any>'.ts(2345) 私のlinterから.私はいくつかのことを試して、他のエラーを得たし、次のと一緒に終了Adding Custom Commands to Cypress Typescript . 私はindex.d.ts ファイル./support 修正した名前空間宣言を保持し、./supporttsconfig.jsoncypress 型エラーを解決したフォルダ.
// index.d.ts
declare namespace Cypress {
  interface Chainable {
    mockExternal(): Chainable<Element>
  }
}
残念ながら、私がモックをインポートするカスタムコマンドの一部は、巨大なエラーを引き起こしました.
Error: Webpack Compilation Error
./node_modules/@angular/router/fesm2015/router.mjs
Module not found: Error: Can't resolve '@angular/common' in 'C:\Users\adunster\Documents\repos\HtmlApp\node_modules\@angular\router\fesm2015'
resolve '@angular/common' in 'C:\Users\adunster\Documents\repos\HtmlApp\node_modules\@angular\router\fesm2015'
  Parsed request is a module
  using description file: C:\Users\adunster\Documents\repos\HtmlApp\node_modules\@angular\router\package.json (relative path: ./fesm2015)
    Field 'browser' doesn't contain a valid alias configuration
    resolve as module
// ... 
私は、私のモックをサイプレスのディレクトリのファイルに複製して、タイプまたはモックのような私の角度プロジェクトで何かを輸入したどんな引用も編集することによってこれを回避しようとしました.それだけで私は私は何も私の財産に割り当てられていないことを見つけるwindow.external 実際にブラウザで表示されました.

どうやって修正したの?


私の最終的な解決は、サイブレスコマンドを完全にスキップして、環境変数に基づくプログラムふるまいを変えることでした.多分、より具体的なNPMスクリプトにこれを洗練しますenvironment.ts ファイル(将来の開発環境と対照的に)将来的に.現在のところ、.external アングルサービスのプロパティは次のように変更されました.
function _external (): any {
  return window.external
}
です.
function _external (): any {
  if (environment.production) {
    return window.external
  } else {
    return new MockCEMRWindow().external
  }
}
今、私は特定のサイプレステストを開発するように、私はMockCEMRWindow.external プロパティをテストする必要がある結果を生成します.それは理想的ではありません、しかし、しばらくの間、それは私がする必要があることをするでしょう、そして、実際には、開発環境を実行しているブラウザーウインドウでの手動テストのためにしばらくの間それをするつもりでした.もっと掘りたいと思いますcy.stub() and cy.spy() 私もチャンスを得るとき.

テストの自動実行


私は、私たちの展開プロセスを自動化するための成長の余地がたくさんあることを確信しています、しかし、今のところ、生産を構築して、展開する方法が現在設定されているルートはNPMスクリプトを通してありますpackage.json . 機能やバグフィックスのコードとテストを完了したら、コードをfresh ブランチをクリックし、NPMスクリプトを実行しますfresh ブランチ、カルマ/ジャスミン単体テストを実行し、テストが失敗しない場合は、ビルドを実行します.(普通のサーバに対しては、実際にデータを半テストするのに使うのと同様です.fresh .)
残念なことに、それはこの状況のためにセットするのが簡単でないか、簡単でないようですpushd コマンドはUNCパスを使用しているので、これは別の週のための冒険になります.しかしサイプレスはここにいくつかの方向を持っているContinuous Integration あなたが次にどこに向かうべきかを探しているならば、ドキュメンテーション.

結論


サイプレスで私の足を濡らして、それがすることができることのいくつかを見た後に、私は実は本当にそれについて興奮しています.それは素晴らしいツールのように見えます、そして、私は私のコードの弾力性を保証するのを助けるためにそれを使うのを待つことができません!
それはあなたの環境に応じて対処する必要がありますいくつかのトリックがありますが、既存のプロジェクトに設定された基礎を得るにはあまり難しくありません.しかし、彼らのチュートリアルは素晴らしいです、そして、彼らのドキュメンテーションは明白で、あとに続くのが簡単です.
私は、私がより典型的なAPI呼び出しとHTTP要求を通して働くページを構築しているならば、それが適当なmockとスタブをセットアップするのがより簡単であるか、少なくともより明確な方向があると思います.それでも、私の環境のユニークな挑戦でさえ、基本的なセットアップは全く難しくありませんでした.ちょうどそれをインストールして起動することを恐れてはいけない!