Увод у јединствено тестирање на Питхону

Управо сте завршили са писањем дела кода и питате се шта да радите. Да ли ћете поднети захтев за повлачење и затражити од саиграча да прегледају код? Или ћете ручно тестирати код?

Требали бисте урадити обе ове ствари, али са додатним кораком: потребно је да јединствено тестирате свој код како бисте били сигурни да код ради како је предвиђено.

Јединствени тестови могу проћи или проћи, а то их чини одличном техником за проверу вашег кода. У овом упутству ћу показати како писати јединствене тестове у Питхону и видећете колико је лако покренути их у вашем пројекту.

Почетак

Најбољи начин на који можете разумети тестирање је ако то радите практично. У ту сврху ћу у датотеку која се зове наме_фунцтион.пи написати једноставну функцију која узима име и презиме и враћа пуно име:

#Generate a formatted full name def formatted_name(first_name, last_name): full_name = first_name + ' ' + last_name return full_name.title()

Функција форматтед_наме () узима име и презиме и комбинује их са размаком између њих да би формирала пуно име. Затим се великим словом ставља прво слово сваке речи. Да бисте проверили да ли овај код функционише, морате да напишете неки код који користи ову функцију. У намес.пи ћу написати једноставан код који омогућава корисницима да уносе своја имена и презимена:

from name_function import formatted_name print("Please enter the first and last names or enter x to E[x]it.") while True: first_name = input("Please enter the first name: ") if first_name == "x": print("Good bye.") break last_name = input("Please enter the last name: ") if last_name == "x": print("Good bye.") break result = formatted_name(first_name, last_name) print("Formatted name is: " + result + ".")

Овај код увози форматтед_наме () из наме_фунцтион.пи и при покретању, омогућава кориснику да унесе низ имена и презимена и приказује форматирана пуна имена.

Јединствени тест и тест случајеви

У Питхоновој стандардној библиотеци постоји модул назван униттест који садржи алате за тестирање вашег кода. Јединствено тестирање проверава да ли су сви специфични делови понашања ваше функције тачни, што ће учинити њихово интеграцију заједно са осталим деловима много лакшим.

Тест пример је збирка јединичних тестова који заједно доказују да функција ради како је предвиђено, у читавом низу ситуација у којима се та функција може наћи и за које се очекује да ће је решити. Тест случај треба да размотри све могуће врсте уноса које функција може добити од корисника, и стога треба да укључи тестове који представљају сваку од ових ситуација.

Полагање теста

Ево типичног сценарија за писање тестова:

Прво треба да направите тест датотеку. Затим увезите униттест модул, дефинишите класу тестирања која се наслеђује од униттест.ТестЦасе и на крају напишите низ метода за тестирање свих случајева понашања ваше функције.

Објашњење по редовима налази се испод следећег кода:

import unittest from name_function import formatted_name class NamesTestCase(unittest.TestCase): def test_first_last_name(self): result = formatted_name("pete", "seeger") self.assertEqual(result, "Pete Seeger")

Прво морате да увезете униттест и функцију коју желите да тестирате, форматтед_наме (). Затим креирате класу, на пример НамесТестЦасе, која ће садржати тестове за вашу функцију форматтед_наме (). Ова класа наслеђује од класе униттест.ТестЦасе.

НамесТестЦасе садржи једну методу која тестира један део форматтед_наме (). Ову методу можете позвати тест_фирст_ласт_наме ().

Имајте на уму да ће се свака метода која започиње са „тест_“ покренути аутоматски када покренете тест_наме_фунцтион.пи.

У оквиру методе теста тест_фирст_ласт_наме (), позивате функцију коју желите да тестирате и чувате повратну вредност. У овом примеру позваћемо форматтед_наме () са аргументима „пете“ и „сеегер“ и сачувати резултат у резултирајућој променљивој.

У последњем реду користићемо методу ассерт. Метод потврде потврђује да се резултат који сте добили подудара са резултатом који сте очекивали. И у овом случају знамо да ће функција форматтед_наме () вратити пуно име с великим почетним словима, па очекујемо резултат „Пете Сеегер“. Да би се ово проверило, користи се униттест-ова метода ассертЕкуал ().

self.assertEqual(result, “Pete Seeger”)

Ова линија у основи значи: Упоредите вредност резултујуће променљиве са „Пете Сеегер“ и ако су једнаке, у реду је, али ако ме не обавесте.

На покретању тест_наме_фунцтион.пи очекује се да добијете ОК што значи да је тест положен.

Ran 1 test in 0.001s OK

Неуспех на тесту

Да бих вам показао како изгледа неуспели тест, модификоваћу функцију форматтед_наме () тако што ћу укључити нови аргумент средњег имена.

Дакле, преписаћу функцију тако да изгледа овако:

#Generate a formatted full name including a middle name def formatted_name(first_name, last_name, middle_name): full_name = first_name + ' ' + middle_name + ' ' + last_name return full_name.title()

This version of formatted_name() will work for people with middle names, but when you test it you will see that the function is broken for people who don’t have a middle name.

So when you run the test_name_function.py you will get the output that looks something like this:

Error Traceback (most recent call last): File “test_name_function.py”, line 7, in test_first_last_name result = formatted_name(“pete”, “seeger”) TypeError: formatted_name() missing 1 required positional argument: ‘middle_name’ Ran 1 test in 0.002s FAILED (errors=1)

In the output you will see information that will tell you all you need to know where the test fails:

  • First item in the output is the Error telling you that at least one test in test case resulted in an error.
  • Next you’ll see the file and method in which the error occurred.
  • After that you will see the line in which the error occurred.
  • And what kind of error it is, in this case we are missing 1 argument “middle_name”.
  • Видећете и број покренутих тестова, време потребно за завршетак тестова и текстуалну поруку која представља статус тестова са бројем грешака које су се догодиле.

Шта урадити када тест није успео

Пролазни тест значи да се функција понаша у складу са оним што се од ње очекује. Међутим, неуспели тест значи да је пред вама још забаве.

Видео сам неколико програмера који радије мењају тест уместо да побољшају код - али немојте то. Проведите мало више времена да бисте решили проблем, јер ће вам то помоћи да боље разумете код и дугорочно уштедите време.

In this example, our function formatted_name() first required two  parameters, and now as it is rewritten it requires one extra: a middle name. Adding a middle name to our function broke the desired behavior of  it. Since the idea is not to make changes to the tests, the best solution is to make middle name optional.

After we do this the idea is to make the tests pass when the first and last name are used, for example “Pete Seeger”, as well as when first, last and middle names are used, for example “Raymond Red Reddington”. So  let’s modify the code of formatted_name() once again:

#Generate a formatted full name including a middle name def formatted_name(first_name, last_name,): if len(middle_name) > 0: full_name = first_name + ' ' + middle_name + ' ' + last_name else: full_name = first_name + ' ' + last_name return full_name.title()

Now the function should work for names with and without the middle name.

And to make sure it still works with “Pete Seeger” run the test again:

Ran 1 test in 0.001s OK
И ово сам намеравао да вам покажем: Увек је боље унети промене у свој код како би одговарао вашим тестовима, него обрнуто. Сада је дошло време да се дода нови тест за имена која имају средње име.

Додавање нових тестова

Напишите нову методу у класу НамесТестЦасе која ће тестирати средња имена:

import unittest from name_function import formatted_name class NamesTestCase(unittest.TestCase): def test_first_last_name(self): result = formatted_name("pete", "seeger") self.assertEqual(result, "Pete Seeger") def test_first_last_middle_name(self): result = formatted_name("raymond", "reddington", "red") self.assertEqual(result, "Raymond Red Reddington")

Након покретања теста, оба теста треба да прођу:

Ran 2 tests in 0.001s OK
Грудњак!

Добро урађено!

Написали сте своје тестове да бисте проверили да ли функција ради користећи имена са или без средњег имена. Пратите други део где ћу говорити више о тестирању на Питхону.

Хвала вам за читање! Погледајте још оваквих чланака на мом фрееЦодеЦамп профилу: //ввв.фреецодецамп.орг/невс/аутхор/горан/ и друге забавне ствари које правим на својој ГитХуб страници: //гитхуб.цом/ГоранАвиани