8

まず、私は Java の世界から来たと言います (これは本当に重要です)。

私はしばらく PHP をコーディングしてきましたが、私が遭遇した問題の 1 つは、コンパイルの欠如が原因で、コンパイル時に簡単に検出できるエラー (たとえば、特定の関数のパラメーターの数が間違っているなど) です。静かに通過できます。

これは、単体テストを追加することでコード カバレッジが増加するにつれて、簡単に検出できます。問題は、たとえば、渡されたパラメーターが正しいことを確認するためにコンストラクターをテストすることは理にかなっていますか? パラメーターの数だけでなく、そのようなパラメーターの内容も意味します (たとえば、パラメーターが null の場合、「ダーティ」オブジェクトの作成を避けるために、特定のオブジェクトが例外を起動する必要があります)。

質問は、私は何年にもわたる Java コードに汚染されすぎているのでしょうか? 結局のところ、コード カバレッジを増やして、見逃された関数を「発見」することは、(本当に) 原始的なコンパイル方法のように感じられるからです。

また、私はすでに開発環境 (PHPStorm) を使用しており、PHPCodeSniffer などのツールも使用しています。

アイデア/提案はありますか?

4

3 に答える 3

5

これは、いくつかのレベルで答えることができる良い質問です。

  1. 言語特性
  2. テスト範囲
  3. ケースツール

1. 言語特性 ご指摘のとおり、PHP 言語の特性は、Java などのより厳密に型指定された言語とは著しく異なります。これは、Java や C# などのより厳密に型指定された言語から来たプログラマーが PHP の動作 (あなたが説明したものなど) の意味を認識していない可能性があるという深刻な問題を引き起こします。これにより、プログラマー側でミスが発生する可能性が生じます (たとえば、コンパイラーが誤ったパラメーターを検出することを知っているため、Java の使用に注意を払わなかったプログラマーは、PHP での開発時に適切な注意を払わない可能性があります)。したがって、この問題に対処するには、より優れたプログラマー教育/監督が必要です (社内コーディング標準、ペア プログラミング、コード レビューなど)。

2. テスト カバレッジ テスト カバレッジ の議論は、プロジェクト固有のものです。現実の世界では、テスト カバレッジのレベルは、主に顧客のエラー許容度によって決まります (これは、システムで発生したエラーの結果によって決まります)。リアルタイム制御システムで実行するソフトウェアを開発している場合は、明らかにより多くのテストを行います。あなたの質問では、選択した言語として PHP を特定しています。これは、重要なシステム インフラストラクチャの Web 対応フロントエンドの数が増え続けることにも等しく当てはまります。コインの反対側では、鉄道模型クラブの単純な Web サイトを開発していて、ニュースレター アプリを開発しているだけの場合、顧客はコンストラクターのバグの可能性を気にしない可能性があります。

3. CASE ツール 最終的には、パラメータの欠落などのエラーを検出できる CASE ツールが利用できることが望ましいでしょう。適切なツールが他にない場合は、独自のツールを作成してみませんか。CASE ツールの作成は、特に言語用のオープンソースの解析エンジンに接続できる場合、ほとんどのプログラマーにとって手の届かないところにはありません。オープンソースに傾倒している場合、これは開始するのに適したプロジェクトである可能性があります。また、おそらくあなたの会社はそのようなソリューションを販売することもできます。

結論 あなたの場合、コンストラクターをテストするかどうかは、基本的に次の質問に帰着します: 私のシステムで障害が発生すると、どのような結果になるでしょうか? このような失敗を回避するために、コンストラクターのテストに余分なリソースを費やすことが経済的に理にかなっている場合は、そうする必要があります。それ以外の場合は、ペア プログラミングやコード レビューなどのより少ないテストでうまくいく可能性があります。

于 2012-11-23T03:51:32.870 に答える
3

無効なパラメーターが設定されている場合、コンストラクターで例外をスローしますか? 明日、来週、来年も同じように動作させたいですか? 次に、それを検証するテストを作成します。

テストは、コードが意図したとおりに動作することを検証します。無効なパラメーターで失敗することは、消費税の計算やユーザーのプロフィール ページの表示と同様に、コードの動作です。

于 2012-11-23T03:46:48.430 に答える
1

コンストラクター、パラメーターの順序、提供されていない場合のデフォルト、およびいくつかの実際の設定をテストします。例えば:

class UTIL_CATEGORY_SCOPE extends UTIL_DEPARTMENT_SCOPE
{
    function __construct($CategoryNo = NULL, $CategoryName = NULL)
    {
        parent::__construct();              // Do Not Pass fields to ensure that the array is checked when all fields are defined.
        $this->DeclareClassFields_();

        $this->CategoryName = $CategoryName;
        $this->CategoryNo   = $CategoryNo;
    }

    private function DeclareClassFields_()
    {
        $this->Fields['CategoryNo']             = new UTIL_ICAP_FIELD_PAIR_FIRST('CCL', 6, ML('Category'), 8);
        $this->Fields['CategoryName']           = new UTIL_ICAP_FIELD_PAIR_SECOND('CCL', 32, ML('Name'), 15, array(), array(), NULL, UTIL_ICAP_FIELD::EDIT_DENY, UTIL_ICAP_FIELD::UPDATE_DENY, 'DES');
    }
}

次に、コンストラクターとその順序をチェックするだけでなく、クラスと継承が変更されていないことを確認するテストを作成します。

public function testObjectCreation()
    {
        $CategoryInfo = new UTIL_CATEGORY_SCOPE();
        $this->assertInstanceOf('UTIL_CATEGORY_SCOPE', $CategoryInfo);
        $this->assertInstanceOf('UTIL_DEPARTMENT_SCOPE', $CategoryInfo);
        $this->assertInstanceOf('UTIL_DATA_STRUCTURE', $CategoryInfo);     // Inherited from UTIL_DEPARTMENT_SCOPE
    }

    public function testConstructFieldOrder()
    {
        $CategoryInfo = new UTIL_CATEGORY_SCOPE(1500, 'Category Name');
        $this->assertEquals(1500, $CategoryInfo->CategoryNo);
        $this->assertEquals('Category Name', $CategoryInfo->CategoryName);
    }

    public function testConstructDefaults()
    {
        $CategoryInfo = new UTIL_CATEGORY_SCOPE();
        $this->assertNull($CategoryInfo->CategoryNo);
        $this->assertNull($CategoryInfo->CategoryName);
    }

    public function testFieldsCreated()
    {
        $CategoryInfo = new UTIL_CATEGORY_SCOPE();
        $this->assertArrayHasKey('CategoryNo', $CategoryInfo->Fields);
        $this->assertArrayHasKey('CategoryName', $CategoryInfo->Fields);
        $this->assertArrayHasKey('DeptNo', $CategoryInfo->Fields);      // Inherited from Parent
        $this->assertArrayHasKey('DeptName', $CategoryInfo->Fields);    // Inherited from Parent
    }
于 2012-11-23T14:43:37.647 に答える