このトピックについて私が話しているビデオへのリンクがあります
このビデオが気に入らない場合は、ここをクリックしてください長いバージョンです。
ソフトウェアは変更可能です。これが「ソフトウェア」と呼ばれる理由であり、その可塑性はハードウェアよりも強いです。優れたエンジニアのチームは、ビジネスの成長に合わせて付加価値を高め続けるシステムを作成し、企業にとって素晴らしい資産となるはずです。
では、なぜ私たちはこれが苦手なのでしょうか?完全に失敗したプロジェクトを何件聞いたことがありますか?あるいは、「レガシー」になり、完全に書き直す必要があります (書き換えも通常は失敗します!)
ソフトウェア システムはどのようにして「失敗」するのでしょうか?正しくなる前に修正することはできないのでしょうか?これが私たちの約束です!
多くの人が Go でシステムを構築することを選択します。これは、Go をより読みやすくすることを期待して多くの選択が行われてきたためです。 [関連する推奨事項: Go ビデオ チュートリアル ]
私のこれまでの Scala でのキャリアと比較すると、首を吊るしたくなる衝動に駆られると思います , Go には 25 個のキーワードと、標準ライブラリやその他の小さなライブラリから構築できる 多数のシステムしかありません。ビジョンは、Go を使用してコードを作成し、6 か月後に振り返ってもまだ意味があるということです。
1974 年、[マニー リーマン] (
https://en.wikipedia.org/wiki/Manny_Lehman...) という名の賢いソフトウェア エンジニアが、ダウンロード Lehman Software Evolution を書きました。法###。 これらの法則は、新たな発展を推進する力と進歩を妨げる力の間のバランスを説明しています。
#継続的変化の法則開発したシステムがレガシーになり、何度も書き直されることを望まない場合、これらの力を理解する必要があります。
明らかに、システムは継続的に変更する必要があります。そうしないと、ますます役に立たなくなってしまいます。しかし、この状況がしばしば無視されるのはなぜですか?
なぜなら、多くの開発チームが成果を上げることでボーナスを得るからです。指定された日付までにプロジェクトを完了すると、次のプロジェクトに進みます。ソフトウェアが「幸運」であれば、少なくともそれを維持するために別のグループに何らかの形で引き渡されるでしょうが、彼らがそれを反復し続けることは確実にありません。 人々は、システムの永続性開発に焦点を当てるのではなく、「迅速な提供」を支援するフレームワークの選択を心配することがよくあります。
あなたが優れたソフトウェア エンジニアであっても、システムの将来のニーズを理解していないと犠牲になる可能性があります。ビジネスが変化すると、あなたが書いた素晴らしいコードは意味がなくなる可能性があります。
リーマンが 1970 年代に大成功を収めたのは、熟考に値するもう 1 つのルールを彼が与えたからです。
複雑さ増大の法則彼が今言いたいのは、「システムが長時間稼働し続けるために、ソフトウェアにますます多くの機能を集中させるだけで、ソフトウェア チームを純粋な機能工場にすることはできない」ということです。長い間。 私たちの知識の状況が変化するにつれて、私たちはシステムの複雑さを引き続き管理しなければなりません。リファクタリング
ソフトウェア開発では、次のような
多くの通常は「良好な」コードです。コードの適切な分離などに注意してください。
#クローズドループ
リファクタリングに焦点を当てます。プログラミングの初日に開発者からよく聞かれるのが、「これをリファクタリングする必要がある」という言葉です。
私や他の多くの人が 自分たちがリファクタリングしていると思っていたことはわかっていますが、それは間違っていました。
Martin Fowler は、人がどのように間違いを犯すかを説明しています
ただし、「リファクタリング」は不適切な場所でよく使用されます。誰かがリファクタリング中に数日間ダウンしたシステムについて話し合った場合、その人はリファクタリングしていないと確信できます。 #########それは何ですか?因数分解
これを行うには、分母を因数分解します、式を # に変換します。
##2/4 1/4 これを 3/4
. に変えることができます。ここからいくつかの重要な教訓を学ぶことができます。
式を分解する場合、式の意味は
変更されません。どちらも
に等しいですが、1/2 を 2/4 に変更すると作業が容易になり、より「分野」に適したものになります。 コードをリファクタリングするときは、現在のシステム要件に「適合」させながら、コードを理解しやすくする方法を見つけるように努める必要があります。重要なのは、
コードの元の動作を変更しないことです。
.
次のメソッドは、特定の ## を使用します。 # language
挨拶func Hello(name, language string) string { if language == "es" { return "Hola, " + name } if language == "fr" { return "Bonjour, " + name } // 想象一下更多的语言 return "Hello, " + name }
if ステートメントが何十もあると不快に感じられ、特定の ## を繰り返し使用する必要があります # language
は、,
挨拶
と一致します。それでは、コードをリファクタリングしましょう。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">func Hello(name, language string) string {
return fmt.Sprintf(
"%s, %s",
greeting(language),
name,
)
}
var greetings = map[string]string {
es: "Hola",
fr: "Bonjour",
//等等...
}
func greeting(language string) string {
greeting, exists := greetings[language]
if exists {
return greeting
}
return "Hello"
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
実際には、このリファクタリングの性質は重要ではありません。重要なのは、コードの動作を変更しなかったことです。 リファクタリングするときは、インターフェイス、新しい型、関数、メソッドなどを追加するなど、好きなことを行うことができます。唯一のルールは、コードの動作を変更できないことです。
コードをリファクタリングするときに機能を変更しないでください
これは非常に重要です。リファクタリング時に機能を変更すると、
のことを同時に行うことになります。ソフトウェア エンジニアとして、私たちはシステムをさまざまなファイル、パッケージ、関数などに分割する方法を学ぶ必要があります。なぜなら、何かの大きな部分を理解しようとするのは難しいことを知っているからです。
一度に多くのことを考えるべきではありません。間違いを犯すことになるからです。私は、開発者が噛みつく以上に噛み砕いたために、多くのリファクタリング作業が失敗するのを目撃してきました。
テストを書かないことを選択した人は、多くの場合、手動テストに依存します。小規模なプロジェクトでない限り、これには膨大な時間がかかり、長期的には将来のシステムの拡張には役に立ちません。
安全にリファクタリングするには、単体テストが必要です。これにより、機能の変更を気にせずにコードをリファクタリングできます
開発者がシステムをどのように実行すべきかに関するドキュメントを作成するのに役立ちます
# 手動テストよりも迅速で信頼性の高いフィードバック
func TestHello(t *testing.T) { got := Hello("Chris", es) want := "Hola, Chris" if got != want { t.Errorf("got %q want %q", got, want) } }
プログラムの実行ステータスを取得したいと考えています
テストを実行します
繰り返し
すべての主要な動作が単体テストされ、1 秒以内にフィードバックが与えられるプロジェクトを用意することは、リファクタリングが必要なときに大胆な決定を下すことを可能にする非常に強力なセーフティ ネットです。これは、リーマン氏が説明する増大する複雑性を管理するのに役立ちます。
一方で、単体テストは実際には
リファクタリングを妨げるという人もいます。正方形の周囲に単体テストを作成して、両辺が等しいことを確認してから、三角形の周囲にいくつかのテストを作成します。三角形が正しくレンダリングされていることを確認したいので、角度の合計が 180 度であると主張し、2 つのテストを実行して確認します。テスト カバレッジは非常に重要で、これらのテストの作成は非常に簡単なので、そうしない理由はありませんか?
数週間後、法律の変更が私たちのシステムに影響を及ぼし、新しい開発者がいくつかの変更を加えました。彼女は今、2 つの三角形よりも 2 つの長方形から正方形を作る方が良いと考えています。
2 つの長方形が正方形を形成します
彼はこのリファクタリングを試し、いくつかの失敗したテストからいくつかのヒントを得ました。彼は本当にコードの重要な機能を壊したのでしょうか?彼女は今、これらの三角形のテストをさらに深く掘り下げて、内部で何が起こっているのかを正確に理解しようと努めなければなりません。
正方形が三角形で構成されていることは実際には問題ではありませんしかし、私たちのテストでは実装の詳細の重要性を誤って高めてしまいました。
単体テストについて人々が不満を言うのを聞くと、それは通常、テストの抽象化レベルが間違っていることが原因です。彼らは皆、実装の詳細をテストし、協力者のコードを執拗に観察し、そしてたくさんの嘲笑をしていました。
この問題は、ユニットテストに対する誤解と、メトリクス (テストカバレッジ) の追求に起因すると思います。
機能のテストだけについて話しているのであれば、システム/ブラック ボックス テストを作成するだけでよいのではないでしょうか?この種のテストは、主要なユーザー ジャーニーを検証する上で多くの価値がありますが、多くの場合、作成にコストがかかり、実行に時間がかかります。このため、フィードバック ループが遅いため、リファクタリングにはあまり役に立ちません。さらに、単体テストと比較すると、ブラック ボックス テストは根本的な問題の解決にはあまり役に立ちません。
それでは、は正しい抽象化レベルでしょうか?
たとえば、Go を使用して銀行システムを開発する場合は、「アカウント」パッケージが必要です。実装の詳細が漏洩せず、統合が容易な API を提供します。
定義上、これらのテストは有用な機能のみをテストできます。これらのユニットを配置すると、必要なときにいつでも自由にリファクタリングでき、ほとんどの場合、テストが妨げられることはありません。
これらは単体テストですか?。単体テストは、私が「ユニット」と表現するものに対するものです。 決して 1 つのクラス/関数などをターゲットにすることはありません。 #これらの概念の結合
リファクタリングが簡単。
ソフトウェアを常に変更する方法に関するリーマンのアイデアのせいで、事前に「完璧な」スケーラブルなシステムを作成しようとして過度に設計し、多くの時間を無駄にする人もいるかもしれません。 。
アジャイル開発は、フィードバックをすぐに得られるように、小規模から始めてソフトウェアを継続的に改善しながら、反復的に作業する必要があることを教えてくれます。ソフトウェアの設計とそれが実際のユーザーとどのように連携するかについて検討し、TDD はこのアプローチを強制します。
TDD は、常にリファクタリングして反復的に提供する開発アプローチを奨励することで、リーマン氏が語る法則やその他の歴史的に学びにくい教訓に対処します。
小さな関数の小さなテストを作成する
テストが有効かどうかを確認する失敗し、明らかなエラーがあります (赤)
テストに合格するための最小限のコードを作成します (緑)
リファクタリング
上記の手順を繰り返します
熟練度が上がるにつれて、これが自然な作業方法となり、作業効率も向上します。どんどんレベルが上がっていきます
プログラムが非「グリーン」状態にあることがわかると、小さなテストユニットがテスト全体を完了するのにそれほど時間はかからないことを望み始めます。 , これは、ちょっとしたトラブルが発生した可能性があることを示しています。
これらのテスト フィードバックを使用すると、いくつかの小規模なアプリケーション機能の安定性を簡単に確認できます。
このソフトウェアの利点は、必要に応じて変更できることです。時間が経つにつれて、いくつかの予測不可能な理由により、ほとんどのソフトウェアはニーズに応じて対応する変更を加える必要がありますが、将来を予測するのは非常に難しいため、最初から無理をしたり過度に設計したりしないでください。
したがって、上記のニーズを満たすためには、ソフトウェアのスケーラビリティを維持する必要があります。そうしないと、ソフトウェアのリファクタリングとアップグレードが必要になったときに状況が非常に悪くなります。
元のアドレス: https://quii.gitbook.io/learn-go-with-tests/meta/why翻訳アドレス: https: //learnku.com/go/t/34095プログラミング関連の知識については、
プログラミング ビデオをご覧ください。 !
以上がなぜ単体テストを行うのか?テストはどのように実施するのですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。