テストと実際のコード間でデータを複製するのは良いですか、悪いですか?たとえば、FooSaver
特定の名前のファイルを特定のディレクトリに保存するPythonクラスがあるとします。
class FooSaver(object):
def __init__(self, out_dir):
self.out_dir = out_dir
def _save_foo_named(self, type_, name):
to_save = None
if type_ == FOOTYPE_A:
to_save = make_footype_a()
elif type == FOOTYPE_B:
to_save = make_footype_b()
# etc, repeated
with open(self.out_dir + name, "w") as f:
f.write(str(to_save))
def save_type_a(self):
self._save_foo_named(a, "a.foo_file")
def save_type_b(self):
self._save_foo_named(b, "b.foo_file")
私のテストでは、これらのファイルがすべて作成されたことを確認したいので、次のように言いたいと思います。
foo = FooSaver("/tmp/special_name")
foo.save_type_a()
foo.save_type_b()
self.assertTrue(os.path.isfile("/tmp/special_name/a.foo_file"))
self.assertTrue(os.path.isfile("/tmp/special_name/b.foo_file"))
これは2つの場所でファイル名を複製しますが、それは良いと思います:反対側に出てくると予想されるものを正確に書き留めることを強制し、タイプミスに対する保護の層を追加し、一般的に物事が機能していると確信させますまさに期待どおり。将来変更a.foo_file
する場合type_a.foo_file
は、テストで検索と置換を行う必要があることを知っていますが、それがあまりに大したことではないと思います。コードとテストの理解が同期していることを確認することと引き換えにテストを更新するのを忘れた場合、むしろ誤検出がいくつかあります。
同僚は、この複製が悪いと考えているので、両側を次のようなものにリファクタリングすることをお勧めします。
class FooSaver(object):
A_FILENAME = "a.foo_file"
B_FILENAME = "b.foo_file"
# as before...
def save_type_a(self):
self._save_foo_named(a, self.A_FILENAME)
def save_type_b(self):
self._save_foo_named(b, self.B_FILENAME)
そしてテストで:
self.assertTrue(os.path.isfile("/tmp/special_name/" + FooSaver.A_FILENAME))
self.assertTrue(os.path.isfile("/tmp/special_name/" + FooSaver.B_FILENAME))
コードが期待どおりに動作していることを確信できないので、これが好きではありません--- out_dir + name
実稼働側とテスト側の両方でステップを複製しました。+
文字列がどのように機能するかについての私の理解の誤りを明らかにすることはなく、タイプミスもキャッチしません。
一方、これらの文字列を2回書き込むよりも明らかに脆弱ではなく、そのような2つのファイルにデータを複製するのは少し間違っているように思えます。
ここには明確な先例がありますか?テストと実稼働コード間で定数を複製しても大丈夫ですか?それとも脆すぎますか?