2016-10-21 14 views
0

私は、2回の間のmsの数を計算する方法を持っています。 time.time()has some accuracy issuesので、私はこれは再現性の観点から、必ずしも理想的ではありません理解ビヘイビアが簡単に定義されないときに、テスト関数の単位を設定する方法はありますか?

orig = time.time() 
# do stuff 
time_duration = time_diff(orig) 

def time_diff(orig_time): 
    return int((time.time() - orig_time) * 1000) 

はそれはに似て使用されています。

実用的な観点から、この機能は十分に機能します。正確な精度は必要ないし、精度が失われることも知っている。

しかし、私の問題は、この機能に依存するサービスをテストするときです。

class ReportingTest(TestCase): 

    def test_time_diff_badly(self): 
     # this approach is bad and I should not even consider it 

     orig = time.time() 

     self.assertEqual(
      time_diff(orig), 
      0) 

    @patch('time.time') 
    def test_time_diff_mocked(self, time_mock): 
     time_mock.return_value = 0 

     self.assertEqual(
      time_diff(0.0015), 
      1.5) 

    def test_time_diff_threshold(self):   
     orig = time.time() 
     dt = time_diff(orig) 

     self.assertLessEqual(dt, 0.10) 
     self.assertGreaterEqual(dt, 0) 

最初は明らかに悪いです:

は、私がいくつかのオプションを持っているようです。私が一貫して返す価値がありません。 Mockingは閾値ベースのアプローチと同様に有効です。私はそれをするとテストを書くことさえ少し無意味に思えるので、私は本当に嘲笑したくない。

この機能をテストするには、より良い方法がありますか?

+0

あなたは 'デフtime_diff(orig_time、END_TIME)として、あなたの関数を定義することができます:'とあなたのコードで ')(' time.timeとしてEND_TIMEを渡し、それにテスト – njzk2

+0

で固定値としておそらくより良いですオプションの引数として終了時刻を渡します: 'def time_diff(orig_time、end_time = None)' - これはそれを呼び出すすべてのコードを編集する必要がありません。 –

答えて

2

バグを検出するための単体テストは存在しません。後で導入されたバグをキャッチするために存在します。あなたのテストが簡単ではないかと心配しないでください。ここで

は、あなたの現在のテストを改善するためのいくつかの方法があります。

  1. time.time()が呼び出されることを前提としないでください。これは現在テストが依存している実装の詳細なので、 が変更された場合にテストが失敗することを確実にするための措置を講じてください。

    time_mock.assert_called() 
    

    嘲笑された内容に応じて、あなたは回数が、それが呼ばれる、またはそれはと呼ばれるものの引数が、アイデアはその基礎となる前提が変化したときに、あなたのテストは失敗にしようとすることであることを確認することをお勧めします。

  2. 異なる戻り値を持つ複数のテストを記述します。特にこの場合、time.time()は決して同じ値を2回返すことはありません。したがって、クラスの値が問題を引き起こす可能性があります。たとえば、time.time()orig_timeより大きい値を返しますが、そうでないと仮定します。

関連する問題