目次
- 1 1. Ano ang Python unittest?
- 2 2. Pangunahing Paggamit ng unittest
- 3 3. Paggamit ng setUp() at tearDown()
- 4 4. Pagsusuri ng mga Dependensiya Gamit ang Mock
- 5 5. Pagpoproseso ng mga Exception at Custom na Assertion
- 6 6. Ang tampok na test discovery ng unittest
- 7 7. Mga tip para sa pagpapabuti ng pagganap gamit ang unittest
- 8 8. Buod at Susunod na Hakbang
1. Ano ang Python unittest?
unittest
ay isang unit testing framework na kasama sa standard library ng Python, at isang mahalagang tool para matiyak ang kalidad ng code. Pinapayagan nito ang mga developer na subukan nang hiwalay ang bawat bahagi ng code, at makahanap ng mga bug nang maaga. Bukod pa rito, nakakatulong ito upang matiyak na ang mga pagbabago sa code ay hindi nasisira ang umiiral na functionality habang patuloy na nagde-develop.Kahalagahan ng Unit Testing
Habang nagiging mas kumplikado ang code, nagiging mahirap tiyakin kung tama ang pakikipag-ugnayan ng iba’t ibang bahagi. Sa pamamagitan ng pag-implement ng unit testing, mas madaling maiwasan ang mga hindi inaasahang bug dulot ng maliliit na pagbabago, at mapanatili ang katatagan ng buong programa.2. Pangunahing Paggamit ng unittest
Ang pangunahing gamit ngunittest
ay lumikha ng isang klase na nagmamana mula sa unittest.TestCase
at magtakda ng mga test method dito. Sa loob ng test method, gamitin ang mga assertion method tulad ng assertEqual()
upang ihambing ang inaasahang resulta sa aktwal na resulta.Halimbawa ng Pangunahing Pagsusulit
Ang sumusunod na code ay isang simpleng halimbawa ng pagsubok sa function naadd(a, b)
.import unittest
# Code na sinusubukan
def add(a, b):
return a + b
# Klase ng pagsusulit
class TestAddFunction(unittest.TestCase):
def test_add_integers(self):
result = add(2, 3)
self.assertEqual(result, 5)
if __name__ == '__main__':
unittest.main()
Sa code na ito, sinusubukan kung tama ang pag-andar ng function na add()
. Ang method na assertEqual()
ay tinitiyak na ang inaasahang halaga ay katumbas ng aktwal na resulta. Sa pamamaraang ito, maaaring mapatunayan na ang function ay tama ang pag-andar sa maraming kaso.Pagpapalawak ng Pagsusulit
aaari kang gumamit ng maraming test method upang subukan ang pag-andar ng function sa iba’t ibang input. Halimbawa, maaari ring subukan ang mga floating-point numbers at ang pagsasama ng mga string.def test_add_floats(self):
result = add(2.5, 3.5)
self.assertAlmostEqual(result, 6.0, places=2)
def test_add_strings(self):
result = add("Hello, ", "World!")
self.assertEqual(result, "Hello, World!")
Sa ganitong paraan, sa pamamagitan ng pagsubok sa pag-andar ng function para sa iba’t ibang uri ng data, makakatiyak na tama ang pag-andar ng function sa iba’t ibang sitwasyon.
3. Paggamit ng setUp() at tearDown()
Upang awtomatikong isagawa ang mga tiyak na proseso bago at pagkatapos ng pagsusulit, gamitin ang mga method nasetUp()
at tearDown()
. Sa ganitong paraan, maihahanda mo ang kinakailangang mga bagay bago patakbuhin ang pagsusulit, at makakapaglinis pagkatapos ng pagtatapos ng pagsusulit.Halimbawa ng setUp()
setUp()
Ang method na ito ay tinatawag palagi bago patakbuhin ang bawat test method, at maaaring pagsamahin ang mga karaniwang proseso ng inisyal na pagsisimula.
code>def setUp(self):
self.temp_value = 42Halimbawa ng tearDown()
tearDown()
Ang method na ito ay isinasagawa pagkatapos ng bawat test method, at gumagawa ng post-processing at paglabas ng mga resources. Halimbawa, magagamit ito para i-disconnect ang koneksyon sa database o magtanggal ng mga pansamantalang file.def tearDown(self):
self.temp_value = None
Sa ganitong paraan, mababawasan ang kalabisan sa test code at mapapanatili ang mas malinis na code.4. Pagsusuri ng mga Dependensiya Gamit ang Mock
Kung ang code na sinusubukan ay nakadepende sa mga panlabas na mapagkukunan (tulad ng database, API, atbp.), maaaring palitan ang mga dependent na bahagi ng mock upang mapabuti ang bilis ng pagpapatakbo ng pagsusuri at magsagawa ng mga pagsusuring maaasahan. Sa paggamit ngunittest.mock
module ng Python, madali itong maisakatuparan.Halimbawa ng Mock
Sa sumusunod na code, pinalitan ang function natime_consuming_function()
na tumatagal ng mahabang oras ng isang mock.from unittest.mock import patch
class TestAddFunction(unittest.TestCase):
@patch('my_module.time_consuming_function')
def test_add_with_mock(self, mock_func):
mock_func.return_value = 0
result = add(2, 3)
self.assertEqual(result, 5)
Sa halimbawang ito, ginagamit ang mock upang magsagawa ng pagsusuri nang hindi tinatawag ang time_consuming_function
. Dahil dito, napapaikli ang oras ng pagsusuri habang nakakakuha ng tamang resulta.
5. Pagpoproseso ng mga Exception at Custom na Assertion
unittest
sa, maaari ring subukan ang paghawak ng mga exception. Halimbawa, upang tiyakin na ang isang exception ay tama ang paglabas sa isang tiyak na sitwasyon, gamitin ang assertRaises()
.Pag-test ng Pagpoproseso ng Exception
Sa susunod na halimbawa, kinukumpirma na nagaganap angZeroDivisionError
.def test_divide_by_zero(self):
with self.assertRaises(ZeroDivisionError):
divide(1, 0)
Ang code na ito ay sumusubok na kapag tinawag ang divide(1, 0)
, magtataas ng ZeroDivisionError
.Paglikha ng Custom na Assertion
Sa mga kaso na hindi kayang tugunan ng mga standard na assertion, maaaring lumikha ng sarili mong custom na assertion method.def assertIsPositive(self, value):
self.assertTrue(value > 0, f'{value} is not positive')
Sa pamamagitan ng paggamit ng custom na assertion, maaari mong tugunan ang mas tiyak na mga senaryo ng pagsubok.6. Ang tampok na test discovery ng unittest
Kapag ginamit mo ang test discovery na tampok ngunittest
, awtomatikong mahahanap at maipapatakbo ang lahat ng test file sa loob ng proyekto. Kapaki-pakinabang ang tampok na ito, lalo na sa malalaking proyekto.Paano gamitin ang test discovery
Upang patakbuhin ang test discovery, gamitin ang sumusunod na utos.python -m unittest discover
Sa pamamagitan nito, lahat ng test_*.py
na file sa tinukoy na direktoryo ay ipapatakbo. Kung nais mong tukuyin ang mga file o direktoryo, gamitin ang mga opsyon tulad ng nasa ibaba.python -m unittest discover -s tests -p "test_*.py"
Sa paggamit ng tampok na ito, maiiwasan mo ang abala ng pagtukoy ng mga test file nang paisa-isa, at mas epektibong mapamamahalaan ang mga test kahit sa malalaking proyekto.7. Mga tip para sa pagpapabuti ng pagganap gamit ang unittest
Kapag mabagal ang bilis ng pagpapatakbo ng mga pagsusulit, bumababa ang kahusayan ng pag-unlad. Dito, magpapakilala kami ng ilang mga tip upang mapabuti ang pagganap ng mga pagsusulit gamit angunittest
.I-optimize ang File I/O
Ang mga pagsusulit na nangangailangan ng pagbabasa at pagsulat sa file ay maaaring mapabilis sa pamamagitan ng pagproseso sa memorya. Sa pamamagitan ng paggamit ngStringIO
, maaari kang lumikha ng isang object na kumikilos tulad ng file sa memorya, na iniiwasan ang disk I/O.from io import StringIO
class TestFileOperations(unittest.TestCase):
def test_write_to_memory(self):
output = StringIO()
output.write('Hello, World!')
self.assertEqual(output.getvalue(), 'Hello, World!')
Sa pamamaraang ito, kahit ang mga pagsusulit na kailangang mag-access ng file ay maaaring mapabilis nang malaki.Gumamit ng Mock
Upang mabawasan ang pag-access sa mga panlabas na mapagkukunan, maaaring gamitin ang mock upang mapabilis ang mga pagsusulit. Pinipigilan nito ang mga pagkaantala mula sa network o database, at nagpapab ng oras ng pagpapatakbo ng pagsusulit. Sa susunod na halimbawa, pinalitan ang tawag sa API ng mock.from unittest.mock import MagicMock
class TestApiCall(unittest.TestCase):
def test_api_response(self):
mock_api = MagicMock(return_value={'status': 'success'})
response = mock_api()
self.assertEqual(response['status'], 'success')
Sa ganitong paraan, sa pamamagitan ng pagsubok ng mga tampok nang hindi umaasa sa mga panlabas na mapagkukunan, maaari kang bumuo ng mas mabilis at mas matatag na kapaligiran para sa pagsusulit.8. Buod at Susunod na Hakbang
Sa artikulong ito, tinalakay namin nang malawakan ang mga batayan ng unit testing gamit angunittest
ng Python, mula sa paggamit ng setup at teardown, pag-mock para sa mga dependent na bahagi, hanggang sa mga teknik para mapabuti ang performance ng mga test.Buod ng mga Pangunahing Punto
- Pangunahing Paggamit: Magmana mula sa
unittest.TestCase
at gamitin ang mga assertion method para lumikha ng mga test. - setUp() / tearDown(): Sa pamamagitan ng pagsasama at pamamahala ng mga karaniwang proseso bago at pagkatapos ng test, pinapabuti ang muling paggamit ng code at nababasa ito.
- Paggamit ng Mock: Dahil maaaring subukan ang mga functionality nang hindi umaasa sa external na resources, malaki ang pagtaas ng kahusayan ng test.
- Test Discovery: Isang kapaki-pakinabang na tampok na nagpapadali ng pamamahala ng mga test sa malalaking proyekto.
- Mga Teknik sa Pagpapabuti ng Performance: Sa pamamagitan ng pagproseso sa memorya at paggamit ng mock, maaaring paikliin ang oras ng pagpapatakbo ng mga test.
Susunod na Hakbang
Kapag napagmaster mo na ang mga batayan ngunittest
, subukan ang mas advanced na mga paraan ng testing. Halimbawa, ang “parameterized testing” na nagpapahintulot mag-test ng maraming input data nang sabay, o paggamit ng coverage tools para suriin ang saklaw ng test sa code, na magpapatibay sa kabuuang test strategy ng proyekto. Maaari mo ring tingnan ang ibang testing framework tulad ng pytest
at palawakin ang mga pagpipilian ayon sa pangangailangan. Ang testing ay mahalagang bahagi ng development. Upang ma-detect ang mga bug nang maaga at mapanatili ang kalidad ng code, dapat nating aktibong isama ang testing.