web-dev-qa-db-ja.com

大きなモノリシックシステムのリファクタリングとドキュメント化

私は新しいプロジェクトに取り組み始めましたが、驚いたことに、ほとんどまったくテストを行わない単一の開発者によって書かれました。残りのテストはバグが多いか、何かが変更されるとエラーが発生しやすくなり、多くのNullPointerExceptionがスローされます。驚いたことに、開始直後にリリースが予定されていたため、コードベースと機能を理解する時間がほとんどありませんでした。

現在、リリース後、コードの品質を改善し、システムを理解する方法を考えています。データベースからサーバーコード、フロントエンドへのリファクタリングが頻繁に行われることはわかっています。また、将来の使用に備えて、仕事の一環として、適切に文書化しています。

私が考えているのは、統合テストから始めて、ユースケースを理解し、適切な単体テストを作成しながら一度に1つずつリファクタリングを開始することです。私は統合テストの作成に慣れており、グーグル操作を行った後、受け入れテストもあることに混乱しました。

私の現在の状況、または同じ状態の誰かを見て、上記のテスト戦略のうちどれが役立つかを知る必要がありますか?とどのように進めるか?

5
CodeYogi

このコードをリファクタリングしないことを強くお勧めします。

ここでは勝利の状況ではありません。追加する新機能は、テストのない既存の機能にバグをもたらす可能性があります。ただし、その既存の機能をリファクタリングすると、他の機能でバグが発生する可能性が高くなります。

「システムをバグが少なくテストしやすいものにするためにある程度の時間を費やす必要がある」としてビジネスにリファクタリングを販売する場合、3か月後にはさらにバグの多いシステムになり、さらにいくつかのテストを行うことでビジネスは満足できなくなります。

さらに、おそらく、システムの要件は「現在実行していること」であることがわかります。そのためのテストを書くのは簡単ではありません。

あなたの最善の策は、新機能に関する確固たる要件を取得し、それらのテストを確実に行うことです。古い機能のバグは、「その機能のテストを書いてもらえますか?機能の要件は何ですか?」と言えるでしょう。

プロジェクトに慣れてきたらのみビットが新しい機能でアップグレードされるので、ビットの置き換えを開始します。

高度なユーザーアドバイス:

製品を100%機能させたい場合は、ビジネスに「大きな書き換え」プロジェクトを導入する必要があります。

これは、開発チームの範囲をはるかに超えています。プログラミングを開始する前に、システムの元の要件と実際にシステムが日々どのように使用されているかを収集して理解する必要があります。

既存のシステム用に別のテスト環境をセットアップする必要があります。書き直しプロジェクトの進行中も、通常のビジネスと同様に通常の開発が継続すると想定します。

これらを取得したら、現在のシステムの機能テストの作成を開始できます。これらが完了するまで、コードに触れないでください。あなたは多くの既存のバグを見つけなければならないでしょう、あるいは私たちは人々が要件が何であると思ったかとシステムが何をするかの間の違いを言いましょうか。これらは解決するために広範な会議を必要とするでしょう、おそらくシステムは正しいです、そして、要件は間違っているかもしれません、多分それらは両方間違っているかもしれません。

機能テストの完全なスイートがあれば、コードを変更することもできます。覚えておいてください。別のチームが他の機能を追加して、ライブに移行する前に「新しいシステム」に複製する必要がある機能を追加していることを覚えておいてください。

これをすべて実行し、通常のチームとしてビジネスを追い越してリリースすると、プロセスの開始時とまったく同じ機能を備えた製品ができます。製品が基本的に問題なく動作している場合、ビジネスに売り込むのは非常に困難です。

6
Ewan

私たちは全員そこにいます、私はいくつかの厄介なプロジェクトを一度リファクタリングしなければなりませんでした。私があなたに言うことができることは、それがかかることができる時間を過小評価しないことです。システムを最初にテストすると、間違いなく作業が簡単になります。

統合テストと受け入れテストのどちらを選択するかは、リファクタリングの大きさによって異なります。受け入れテストは、システム全体をテストするために作成されます。一般に、例または使用シナリオとして表されます。例:ユーザーとして、ユーザー名とパスワードを入力し、ログインボタンを押します。次に、ようこそ画面が表示されます。

すべての機能の受け入れテストが完了したら、自信を持ってリファクタリングを開始できます。プロジェクトをさまざまなサービスに分割したり、プログラミング言語自体を変更したりすることもできます。システムが大きい場合、これらのテストを最初から作成することは非常に時間がかかります。

一部の機能の統合テストを記述してからリファクタリングする場合は、プロジェクトの一部が変更されないと想定していることを意味します。例:エンドポイントをテストする場合、このエンドポイントは変更されないと想定します。また、リファクタリング後も同じインターフェースになります。

決定は、どれだけの時間を費やしているか、プロジェクトがどれほど厄介であるかによって異なります。私が提案するのは、現実的で、高すぎないことです。いくつかの統合テストから始めて、リファクタリングを行い、新しい機能を追加し続け、同時にリファクタリングします。結局、とにかく完璧なソフトウェアはありません。

幸運を

3

前回の回答は非常に優れており、従う必要があるため、厳密に単体テストではない質問の側面、つまり「および続行方法」について説明します。部。

プロジェクトがいかにうまく組織されているかを自問してください。意味のあるクラスと関数に適切に分割されていますか?親クラスとインターフェースは適切に使用されていますか?未使用または冗長なコードは削除されましたか?データがプログラムを通過して処理されるときの明確なワークフローはありますか?各クラスが何のために使用されているかを示すために、コードは個々の関数レベルと上位クラスレベルの両方でよくコメントされていますか?また、要件や設計計画などの優れたドキュメントはありますか?プロジェクトはこれらの点で素晴​​らしいか恐ろしいかもしれません。それはすべて、前の開発者と彼らがプログラムを作成しなければならなかった条件に依存します。また、優れた開発者であっても、変化する要件と限られた時間で作業せざるを得ない場合は、実装が不十分なプログラムを作成できます。

Visual StudioまたはIDEを同様のインテリセンスのような機能で使用している場合、作業はより簡単になります。

最初のステップは、プロジェクトがまだソース管理されていない場合は、ソース管理にすることです。それが最も重要です。次に、未使用のコードや変数を削除します。その後、少なくともいくつかのクラスを読み、それぞれのクラスを理解します。そのようなコメントが存在しない場合は、「戦略的」レベルでクラスを説明するコメントを追加します。たとえば、クラスがいつ使用され、プログラム全体に対して何が行われるかなどです。他の作業を行う前に、いくつかのクラスでこれを行ってください。これで、これらのクラスの単体テストの作成を開始できます。クラスが肥大化しているように見える場合は、そのプライベート関数と内部関数を統合または再編成してから、そのパブリック関数に取り組むことができます。繰り返されるコードや冗長なコードがある場合は、必要に応じて、それらを個別のクラス/関数/その他に分割できます。

十分なクラスを通過すると、おそらく親クラスまたはインターフェースを共有できるいくつかが表示されます。そのインターフェースを作成し、必要に応じて参照と呼び出しを更新して、可能な限り親/インターフェースを参照できるようにします。これにより、クラス間の変動を処理するために使用された多くの条件ステートメントを削除できるようになります。

最後に、(前の開発者がまったく優れていた場合)すべてがそれと同じ方法で行われたのには理由があることを覚えておいてください。最初にプログラムを書いた人以上の知識があると思い込まないでください。セグメントは、開発者がそれをプログラムするためのより良い方法を知らなかったために不十分な場合がありますが、特定の要件または言語やシステムの癖のためにある場合があります。

1
user3685427