2010-03-27 8 views
3

J'apprends juste à faire des tests unitaires. Je suis sur Python/nose/wing IDE.Tests unitaires en python avec nez: Faire des tests séquentiels

(The project que j'écris des tests pour un cadre de simulations, et entre autres choses, il vous permet d'exécuter des simulations à la fois synchrone et asynchrone, et les résultats de la simulation doivent être les mêmes dans les deux.)

Le truc, c'est que certains de mes tests utilisent des résultats de simulation créés dans d'autres tests. Par exemple, synchronous_test calcule une certaine simulation en mode synchrone, mais je veux ensuite la calculer en mode asynchrone et vérifier que les résultats sont identiques.

Comment structurer ceci? Est-ce que je les mets tous dans une fonction de test, ou fais un asynchronous_test séparé? Est-ce que je passe ces objets d'une fonction de test à une autre? De plus, gardez à l'esprit que tous ces tests passeront par un générateur de test, donc je peux faire les tests pour chacun des paquets de simulation inclus avec mon programme.

+0

Pourriez-vous indiquer une classe spécifique que vous souhaitez tester? –

+0

bebraw, je ne comprends pas votre question. Je veux tester les fonctions 'simulate' et' list_simulate', et la classe 'Project', et d'autres choses. –

+0

D'accord. Considérant que le projet est open source, j'ai pensé qu'il pourrait être amusant de lire du code réel. :) –

Répondre

6

Vous pouvez ajouter des tests qui ont besoin de calculer une fois par classe à la « configuration » de cette classe. A titre d'exemple:

from nose.tools import * 
class Test_mysim(): 
    def setup(self): 
     self.ans = calculate_it_once() 

    def test_sync(self): 
     ans=calculate_it_sync() 
     assert_equal(ans,self.ans) 

    def test_async(self): 
     ans=calculate_it_async() 
     assert_equal(ans,self.ans) 
+0

Et que se passe-t-il lorsque 'calculate_it_once()' échoue? –

+1

J'ai supposé que vous connaissiez la 'réponse' (peut-être en utilisant random.setseed() ou autre). Si non, alors le mieux que vous pouvez faire est d'affirmer que sync et async sont les mêmes, et * que * est le test. J'ai bifurqué votre code, mais je n'ai pas eu l'occasion de le regarder. –

6

En général, je recommanderais pas en faisant dépendre un test d'un autre. Faites le synchrone_test, faites le test asynchrone, comparez-les chacun à la sortie correcte attendue, pas les uns aux autres.

donc quelque chose comme:

class TestSimulate(TestCase): 
    def setup(self): 
     self.simpack = SimpackToTest() 
     self.initial_state = pickle.load("initial.state") 
     self.expected_state = pickle.load("known_good.state") 

    def test_simulate(self): 
     state = simulate(self.simpack, self.initial_state) 
     # assert_equal will require State to implement __eq__ in a meaningful 
     # way. If it doesn't, you'll want to define your own comparison 
     # function. 
     self.assert_equal(self.expected_state, state) 

    def test_other_simulate(self): 
     foo = OtherThing(self.simpack) 
     blah = foo.simulate(self.initial_state) 
     state = blah.state 
     self.assert_equal(self.expected_state, state) 
+0

Alors * où * dois-je calculer la sortie correcte attendue? Parce que le calcul de cette sortie est quelque chose qui doit être testé par lui-même. –

+0

Et comment testez-vous * ça *? Comparez-le à ... lui-même? Vous devez avoir connu une bonne sortie quelque part. Chargez-le à partir d'un cornichon? (réponse mise à jour avec le code) – keturn

+0

Je suppose que vous avez un point. Bien que je ne vais pas charger à partir d'un pickle-- pas assez facile de faire des changements de cette façon. Je pense que je vais envisager de le faire comme dans l'exemple de Gregg Lind. Une question: Pensez-vous que ce soit mauvais si je mets juste plusieurs tests dans une fonction continue? Alors je n'aurai pas à m'inquiéter de ces choses, et si une chose échoue, je devrai la réparer quand même. –