FrontendでTDDを使用して強力なJSソフトウェアを作成
この文章は、金正煥(キム・ジョンファン)氏の講義を聞いた後、整理して復習したものだ. 課の内容は私の理解の方向と少し違うかもしれません.
TDDを利用してテストコードをずっと抽出し、レンガを1階ずつ開発してきました.これは私の長い間の仕事の経験です.
個人的には、NodeJSプロジェクトを行い、少しずつ応用してみるTDDはとても甘いです.
スタックされたテストコードとコードが格納されるたびに、自動テストが行われ、緑で描画されます.
カバーするときもナレーション効果が出る心配はありません.
ソースコードを久しぶりに見ても、何度かテストを振り返るだけで開発を再開できます.
だからフロントでもTDDを使いたい…
長所より難しいところがたくさんあります.
どうしてそうなるの?
授業中に話す.
フロントエンドテストは難しいです.
その作成はテストしにくいからです.
関心事項の分離はまったく実現していない.
最近谁がモジュールを使わないでこのように使うことができます...
任意のモジュールモード方式を採用し,グローバル変数を乱さずにモジュール形式で実現する.
モジュールは、単一の責任原則を実現するために依存性を注入しなければならない.
次のソースコードは、clickCounter、updateEL注入で使用します.
結合度を下げ、凝集度を高める
依存性が注入されているかどうかをテストするにはどうすればいいですか?
注入された変数がない場合は、エラーが発生し、テストされます.
B関数はA関数を呼び出しますが、B関数のテストコードでA関数を検証する必要がありますか?
各関数呼び出しの関係に対してテストコードを1つずつ記述すると,テストはかなり困難になる.
では、B関数のテストでは、A関数をどのようにテストすればいいのでしょうか.
B関数を呼び出すときにA関数を呼び出すかどうかをテストできますか?
このとき必要なテスト関数は
spyをインプラントすると、オブジェクトを監視する方法.
Frontend JSはTDDが使えますか?
TDDはいいですね
TDDを利用してテストコードをずっと抽出し、レンガを1階ずつ開発してきました.これは私の長い間の仕事の経験です.
個人的には、NodeJSプロジェクトを行い、少しずつ応用してみるTDDはとても甘いです.
スタックされたテストコードとコードが格納されるたびに、自動テストが行われ、緑で描画されます.
カバーするときもナレーション効果が出る心配はありません.
ソースコードを久しぶりに見ても、何度かテストを振り返るだけで開発を再開できます.
先端でTDDは使えないのでしょうか?
だからフロントでもTDDを使いたい…
長所より難しいところがたくさんあります.
どうしてそうなるの?
テストしにくいソースコード。
授業中に話す.
フロントエンドテストは難しいです.
その作成はテストしにくいからです.
テストしにくいソースコード
<button onclick="counter++; countDisplay()">증가</button>
<span id="counter-display">0</span>
<script>
let counter = 0
function countDisplay() {
const el = document.getElementById("counter-display")
el.innerHTML = counter
}
</script>
このコードの問題は何ですか?関心事項は分離していない
<button onclick="counter++; countDisplay()">증가</button>
この線はボタンを作成したり、変数を増やしたり、表示したりします.関心事項の分離はまったく実現していない.
グローバル変数を汚す
counter
変数とcountDisplay
関数はグローバルとして宣言される.最近谁がモジュールを使わないでこのように使うことができます...
再利用しにくい
const el = document.getElementById("counter-display")
注目事項も分離されていないため、elementIdを指定しても再利用しにくい.では、どのようにコードを書くとテストが便利になりますか?
まずモジュール化の方法を理解してみましょう。
任意のモジュールモード方式を採用し,グローバル変数を乱さずにモジュール形式で実現する.
var App = App || {}
App.Person = initName => {
let name = initName
return {
getName: () => name,
setName: newName => {
name = newName
},
}
}
このように実装される任意のモジュールは、以下のように使用される.const person = App.Person("jone")
console.log(person.getName()) // jone
person.setName("doe")
console.log(person.getName()) // doe
TDD思考—注入依存性
モジュールは、単一の責任原則を実現するために依存性を注入しなければならない.
次のソースコードは、clickCounter、updateEL注入で使用します.
結合度を下げ、凝集度を高める
var App = App || {}
App.ClickCountView = (clickCounter, updateEl) => {
return {
updateView() {
updateEl.innerHTML = clickCounter.getValue()
},
increaseAndUpdateView() {
clickCounter.increase()
this.updateView()
},
}
}
テストメソッド
依存項目を入力するかどうかをテスト
依存性が注入されているかどうかをテストするにはどうすればいいですか?
注入された変数がない場合は、エラーが発生し、テストされます.
// ClickCounterView.spec.js
describe("의존성 주입 테스트", () => {
it("ClickCounter를 주입하지 않으면 에러를 던진다", () => {
const clickCounter = null
const updateEl = document.createElement("span")
const actual = () => App.ClickCountView(clickCounter, updateEl)
expect(actual).toThrowError()
})
it("updateEl를 주입하지 않으면 에러를 던진다", () => {
const clickCounter = App.ClickCounter()
const updateEl = null
const actual = () => App.ClickCountView(clickCounter, updateEl)
expect(actual).toThrowError()
})
})
// ClickCountView.js
var App = App || {}
App.ClickCountView = (clickCounter, updateEl) => {
if (!clickCounter) throw new Error()
if (!updateEl) throw new Error()
return {
// ...
}
}
ClickCounterView.spec.js
のactual
およびexpect(actual).toThrowError()
に注意してください.呼び出すかどうかをテスト
B関数はA関数を呼び出しますが、B関数のテストコードでA関数を検証する必要がありますか?
各関数呼び出しの関係に対してテストコードを1つずつ記述すると,テストはかなり困難になる.
では、B関数のテストでは、A関数をどのようにテストすればいいのでしょうか.
B関数を呼び出すときにA関数を呼び出すかどうかをテストできますか?
このとき必要なテスト関数は
spyOn
である.// ClickCounterView.spec.js
describe("increaseAndUpdateView()는", () => {
it("ClickCounter의 increase 를 실행한다", () => {
spyOn(clickCounter, "increase")
view.increaseAndUpdateView()
expect(clickCounter.increase).toHaveBeenCalled()
})
it("updateView를 실행한다", () => {
spyOn(view, "updateView")
view.increaseAndUpdateView()
expect(view.updateView).toHaveBeenCalled()
})
})
spyOn
とspyOn(객체명, "메서드명")
を一緒に使用します.spyをインプラントすると、オブジェクトを監視する方法.
expect(view.updateView).toHaveBeenCalled()
を確認できます.// ClickCountView.js
var App = App || {}
App.ClickCountView = (clickCounter, updateEl) => {
// ...
return {
updateView() {
updateEl.innerHTML = clickCounter.getValue()
},
increaseAndUpdateView() {
clickCounter.increase()
this.updateView()
},
}
}
Reference
この問題について(FrontendでTDDを使用して強力なJSソフトウェアを作成), 我々は、より多くの情報をここで見つけました https://velog.io/@cckn/Frontend에서-TDD를-이용해-견고한-JS-소프트웨어-만들기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol