Najpierw pytanie, a następnie wyjaśnienie, jeśli jesteś zainteresowany.Generowanie testów py.test w python
W kontekście py.test, w jaki sposób wygenerować duży zestaw funkcji testowych z małego zestawu szablonów funkcji testowych?
Coś jak:
models = [model1,model2,model3]
data_sets = [data1,data2,data3]
def generate_test_learn_parameter_function(model,data):
def this_test(model,data):
param = model.learn_parameters(data)
assert((param - model.param) < 0.1)
return this_test
for model,data in zip(models,data_sets):
# how can py.test can see the results of this function?
generate_test_learn_parameter_function(model,data)
Objaśnienie:
Próbuję ciężko dostać się do testów jednostkowych. Koduję dla "nauki", ponieważ piszę kod, który, jak sądzę, jest skomplikowany matematycznie, ale nie aż tak źle z punktu widzenia programowania, tj. Mam do wyboru pięć funkcji do przetestowania. To, że pochodzę z "nauki" oznacza, że jestem całkiem nowy w testowaniu jednostkowym, ale przekonałem moich kumpli z CS, że to The Thing To Do.
Kod, który piszę, ma strukturę modelu, niektóre dane i uczy się parametrów modelu. Zatem moje testy jednostkowe składają się z kilku struktur modelowych i wstępnie wygenerowanych zestawów danych, a następnie zestawu około 5 zadań uczenia maszynowego, które należy wykonać dla każdej struktury + danych.
Więc jeśli to zaksięguję, potrzebuję jednego testu na model na zadanie. Za każdym razem, gdy wymyślam nowy model, muszę skopiować i wkleić 5 zadań, zmieniając, która marynowana struktura + dane wskazuję. Wydaje mi się, że to kiepska praktyka. Idealnie byłoby 5 funkcji szablonu, które definiują każde z 5 zadań, a następnie wypluwają funkcje testowe dla listy struktur, które określam.
Googling o prowadzi mnie do a) fabryk lub b) zamknięć, z których oba powodują mój mózg i sugerują mi, że musi być łatwiejszy sposób, ponieważ problem ten musi być regularnie napotykany przez odpowiednich programistów. Więc jest tam?
EDYCJA: A oto jak rozwiązać ten problem!
def pytest_generate_tests(metafunc):
if "model" in metafunc.funcargnames:
models = [model1,model2,model3]
for model in models:
metafunc.addcall(funcargs=dict(model=model))
def test_awesome(model):
assert model == "awesome"
ten będzie miał zastosowanie testu test_awesome do każdego modelu w moim liście modeli! Dzięki @dfichter!
(UWAGA: Zawsze twierdzą, że przechodzi, btw)
Generalnie jest to zły pomysł, aby wygenerować kod testowy dynamicznie tak. Ponieważ musisz napisać testy kodu testowego itp. "Skopiuj i wklej 5 zadań" Myślę, że to pokazuje, że zamiast generować nowy kod lub wklejać kopie, możesz znaleźć podobieństwa, które twoje funkcje mogą przetestować, nie wiedząc dokładnie, co one "Testowanie. – Falmarri
W tej chwili piszę testy, które wyglądają jak def test_learn: dla modelu w modelach: assert (błąd
@Falmarri: http://en.wikipedia.org/wiki/Copy_and_paste_programming Unikajcie tego prawie na wszystkie koszty. – lpapp