Avec Jupyter, PyHamcrest et un petit code de test qui les relie ensemble, vous pouvez enseigner n'importe quel élément Python qui fonctionne pour les tests unitaires.
Tutoriel vidéo Python la colonne vous donnera une introduction détaillée~
Certaines choses à propos de la communauté Ruby m'ont toujours impressionné, deux exemples étant l'engagement envers les tests et l'accent mis sur la facilité de démarrage. Le meilleur exemple des deux est Ruby Koans, où vous pouvez apprendre Ruby en corrigeant des tests.
Nous pourrions faire mieux si nous pouvions également intégrer ces outils incroyables à Python. Oui, en utilisant Jupyter Notebook, PyHamcrest et un petit code de colle semblable à du ruban adhésif, nous pouvons créer un didacticiel comprenant des instructions, du code de travail et du code à corriger.
Tout d'abord, vous avez besoin d'une "bande". En règle générale, vous utiliserez un astucieux testeur de ligne de commande comme pytest ou vertu pour effectuer vos tests. Souvent, vous ne l’exécuterez même pas directement. Vous utilisez un outil comme tox ou nox pour l'exécuter. Cependant, avec Jupyter, vous devez écrire un petit morceau de code Glue dans lequel vous pouvez exécuter le test directement.
Heureusement, ce code est court et simple :
import unittest def run_test(klass): suite = unittest.TestLoader().loadTestsFromTestCase(klass) unittest.TextTestRunner(verbosity=2).run(suite) return klass复制代码
Maintenant, l'équipement est prêt pour votre première séance d'entraînement.
Quand on enseigne, c'est toujours une bonne idée de commencer par un exercice simple pour renforcer la confiance.
Alors, corrigeons un test très simple :
@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)复制代码
« Changez uniquement cette ligne » est une balise utile pour les étudiants. Il indique exactement ce qui doit être modifié. Sinon, les étudiants peuvent corriger le test en remplaçant la première ligne par return
.
Dans ce cas, la solution est simple :
@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复制代码
Bientôt, cependant, les assertions natives de la unittest
bibliothèque se révéleront insuffisantes. Dans pytest
, ce problème est résolu en réécrivant le bytecode dans assert
pour avoir des propriétés magiques et diverses heuristiques. Mais ce n’est pas facile à réaliser dans le notebook Jupyter. Il est temps de trouver une bonne bibliothèque d'assertions : 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))复制代码
PyHamcrest n'est pas seulement bon pour les assertions flexibles, il est également bon pour les messages d'erreur clairs. Pour cette raison, le problème est évident. [1, 5, 3]
ne contient pas 2
et a l'air moche :
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)复制代码
@run_test class TestList(unittest.TestCase): def test_equality(self): things = [1, 2, # 改完的行 3] assert_that(things, has_items(1, 2, 3))复制代码
En utilisant Jupyter, PyHamcrest et un petit code de colle de test, vous pouvez enseigner n'importe quel sujet Python adapté aux tests unitaires.
Par exemple, ce qui suit permet de démontrer les différences entre les différentes manières dont Python supprime les espaces des chaînes.
test_equality (__main__.TestList) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.001s OK复制代码
Idéalement, les étudiants se rendront compte que .lstrip()
et .rstrip()
répondront à leurs besoins. Mais s'ils ne le font pas et essaient plutôt d'utiliser .strip()
partout :
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)复制代码
, ils recevront un message d'erreur différent qui montre trop d'espaces supprimés :
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)复制代码
dans un In des tutoriels plus réalistes, il y aura plus d'exemples et plus d'explications. Cette technique d'utilisation de Jupyter Notebook peut être utilisée pour certains exemples, et certains exemples doivent être corrigés. Elle peut être utilisée pour l'enseignement en temps réel, pour des cours vidéo et même à d'autres fins dispersées, permettant aux étudiants de terminer un didacticiel en. eux-mêmes.
Partagez vos connaissances maintenant !
Plus de recommandations d'apprentissage gratuites connexes : Tutoriel vidéo Python
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!