Jupyter、PyHamcrest、およびそれらを結び付ける小さなテスト コードを使用すると、単体テストに適用されるあらゆる Python コンテンツを教えることができます。
Python ビデオ チュートリアル列で詳細な紹介をします~
Ruby コミュニティに関するいくつかの点で私は常に感銘を受けています。その 2 つの例は、テストへの取り組みと、簡単に始められることの重視です。両方の最良の例は、テストを修正することで Ruby を学習できる Ruby Koans です。 これらの素晴らしいツールを Python に導入できれば、さらに改善できるはずです。はい、Jupyter Notebook、PyHamcrest、およびダクトテープのような小さな接着コードを使用して、手順、動作するコード、修正が必要なコードを含むチュートリアルを作成できます。 まず、「テープ」が必要です。通常、テストを行うには、pytest や Virtue などの気の利いたコマンドライン テスターを使用します。多くの場合、直接実行することさえありません。実行するにはtoxやnoxなどのツールを使用します。ただし、Jupyter では、テストを直接実行できる小さな接着コードを作成する必要があります。 幸いなことに、このコードは短くてシンプルです:import unittest def run_test(klass): suite = unittest.TestLoader().loadTestsFromTestCase(klass) unittest.TextTestRunner(verbosity=2).run(suite) return klass复制代码これで、最初の練習セッションに向けた準備が整いました。 教えるときは、自信をつけるために簡単な練習から始めることをお勧めします。 それでは、非常に簡単なテストを修正してみましょう:
@run_test class TestNumbers(unittest.TestCase): def test_equality(self): expected_value = 3 # 只改这一行 self.assertEqual(1+1, expected_value)复制代码
test_equality (__main__.TestNumbers) ... FAIL ====================================================================== FAIL: test_equality (__main__.TestNumbers) ---------------------------------------------------------------------- Traceback (most recent call last): File "<ipython-input-7-5ebe25bc00f3>", line 6, in test_equality self.assertEqual(1+1, expected_value) AssertionError: 2 != 3 ---------------------------------------------------------------------- Ran 1 test in 0.002s FAILED (failures=1)复制代码「この行だけを変更してください」は学生にとって便利なタグです。何を変更する必要があるかを正確に示します。それ以外の場合、学生は最初の行を
return に変更することでテストを修正できます。
@run_test class TestNumbers(unittest.TestCase): def test_equality(self): expected_value = 2 # 修复后的代码行 self.assertEqual(1+1, expected_value)复制代码
test_equality (__main__.TestNumbers) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.002s OK复制代码ただし、すぐに、
unittest ライブラリのネイティブ アサーションでは不十分であることが判明します。
pytest では、この問題は
assert のバイトコードを書き換えて魔法のプロパティとさまざまなヒューリスティックを持たせることで解決されます。しかし、これを Jupyter Notebook で実現するのは簡単ではありません。良いアサーション ライブラリである PyHamcrest を発掘する時期が来ました。
from hamcrest import * @run_test class TestList(unittest.TestCase): def test_equality(self): things = [1, 5, # 只改这一行 3] assert_that(things, has_items(1, 2, 3))复制代码
test_equality (__main__.TestList) ... FAIL ====================================================================== FAIL: test_equality (__main__.TestList) ---------------------------------------------------------------------- Traceback (most recent call last): File "<ipython-input-11-96c91225ee7d>", line 8, in test_equality assert_that(things, has_items(1, 2, 3)) AssertionError: Expected: (a sequence containing <1> and a sequence containing <2> and a sequence containing <3>) but: a sequence containing <2> was <[1, 5, 3]> ---------------------------------------------------------------------- Ran 1 test in 0.004s FAILED (failures=1)复制代码PyHamcrest は、柔軟なアサーションに優れているだけでなく、明確なエラー メッセージにも優れています。このため、問題は明らかです。
[1, 5, 3] には
2 が含まれておらず、見苦しくなります:
@run_test class TestList(unittest.TestCase): def test_equality(self): things = [1, 2, # 改完的行 3] assert_that(things, has_items(1, 2, 3))复制代码
test_equality (__main__.TestList) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.001s OK复制代码Jupyter、PyHamcrest、および小さなテスト グルー コードを使用すると、任意の内容を教えることができます。単体テストに適用できる Python トピック。 たとえば、次の例は、文字列から空白を削除する Python のさまざまな方法の違いを示しています。
source_string = " hello world " @run_test class TestList(unittest.TestCase): # 这是个赠品:它可以工作! def test_complete_strip(self): result = source_string.strip() assert_that(result, all_of(starts_with("hello"), ends_with("world"))) def test_start_strip(self): result = source_string # 只改这一行 assert_that(result, all_of(starts_with("hello"), ends_with("world "))) def test_end_strip(self): result = source_string # 只改这一行 assert_that(result, all_of(starts_with(" hello"), ends_with("world")))复制代码
test_complete_strip (__main__.TestList) ... ok test_end_strip (__main__.TestList) ... FAIL test_start_strip (__main__.TestList) ... FAIL ====================================================================== FAIL: test_end_strip (__main__.TestList) ---------------------------------------------------------------------- Traceback (most recent call last): File "<ipython-input-16-3db7465bd5bf>", line 19, in test_end_strip assert_that(result, AssertionError: Expected: (a string starting with ' hello' and a string ending with 'world') but: a string ending with 'world' was ' hello world ' ====================================================================== FAIL: test_start_strip (__main__.TestList) ---------------------------------------------------------------------- Traceback (most recent call last): File "<ipython-input-16-3db7465bd5bf>", line 14, in test_start_strip assert_that(result, AssertionError: Expected: (a string starting with 'hello' and a string ending with 'world ') but: a string starting with 'hello' was ' hello world ' ---------------------------------------------------------------------- Ran 3 tests in 0.006s FAILED (failures=2)复制代码理想的には、生徒は
.lstrip() と
.rstrip() が自分たちのニーズを満たしていることに気づくでしょう。しかし、それを行わず、あらゆる場所で
.strip() を使用しようとすると、
source_string = " hello world " @run_test class TestList(unittest.TestCase): # 这是个赠品:它可以工作! def test_complete_strip(self): result = source_string.strip() assert_that(result, all_of(starts_with("hello"), ends_with("world"))) def test_start_strip(self): result = source_string.strip() # 改完的行 assert_that(result, all_of(starts_with("hello"), ends_with("world "))) def test_end_strip(self): result = source_string.strip() # 改完的行 assert_that(result, all_of(starts_with(" hello"), ends_with("world")))复制代码
test_complete_strip (__main__.TestList) ... ok test_end_strip (__main__.TestList) ... FAIL test_start_strip (__main__.TestList) ... FAIL ====================================================================== FAIL: test_end_strip (__main__.TestList) ---------------------------------------------------------------------- Traceback (most recent call last): File "<ipython-input-17-6f9cfa1a997f>", line 19, in test_end_strip assert_that(result, AssertionError: Expected: (a string starting with ' hello' and a string ending with 'world') but: a string starting with ' hello' was 'hello world' ====================================================================== FAIL: test_start_strip (__main__.TestList) ---------------------------------------------------------------------- Traceback (most recent call last): File "<ipython-input-17-6f9cfa1a997f>", line 14, in test_start_strip assert_that(result, AssertionError: Expected: (a string starting with 'hello' and a string ending with 'world ') but: a string ending with 'world ' was 'hello world' ---------------------------------------------------------------------- Ran 3 tests in 0.007s FAILED (failures=2)复制代码のように、削除された空白が多すぎることを示す別のエラー メッセージが表示されます。 # #
source_string = " hello world " @run_test class TestList(unittest.TestCase): # 这是个赠品:它可以工作! def test_complete_strip(self): result = source_string.strip() assert_that(result, all_of(starts_with("hello"), ends_with("world"))) def test_start_strip(self): result = source_string.lstrip() # Fixed this line assert_that(result, all_of(starts_with("hello"), ends_with("world "))) def test_end_strip(self): result = source_string.rstrip() # Fixed this line assert_that(result, all_of(starts_with(" hello"), ends_with("world")))复制代码
test_complete_strip (__main__.TestList) ... ok test_end_strip (__main__.TestList) ... ok test_start_strip (__main__.TestList) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.005s OK复制代码
より現実的なチュートリアルでは、より多くの例と説明が追加されます。 Jupyter Notebook を使用するこのテクニックは、いくつかの例に使用できますが、いくつかの例は修正が必要です。リアルタイムの教育、ビデオ レッスン、さらにはその他の分散した目的にも使用でき、学生は次の手順でチュートリアルを完了できます。彼ら自身。
今すぐ知識を共有しましょう!
その他の関連する無料学習の推奨事項:
以上がJupyter Notebook を使用して Python を学習するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。