рдкреЗрд╢ рд╣реИ рдкрд╛рдЗрдерди рдореЗрдВ рдкрд░реАрдХреНрд╖рдгред рднрд╛рдЧ реи

рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░!

рд╣рдо рдкрд╛рдпрдерди рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдкрд░рд┐рдЪрд┐рдд рдкрд░ рд▓реЗрдЦ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдЖрдкрдХреЗ рдкрд╛рдпрдерди рдбреЗрд╡рд▓рдкрд░ рдкрд╛рдареНрдпрдХреНрд░рдо рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдкрдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рд╣реИред

Django рдФрд░ рдлреНрд▓рд╛рд╕реНрдХ рд╡реЗрдм рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг

рдпрджрд┐ рдЖрдк рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Django рдпрд╛ рдлреНрд▓рд╛рд╕реНрдХ, рддреЛ рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдФрд░ рдЪрд▓рд╛рдиреЗ рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдВрддрд░ рдХреЛ рдпрд╛рдж рд░рдЦрдиреЗ рдпреЛрдЧреНрдп рд╣реИред

рд╡реЗ рдЕрдиреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рд╕реЗ рдХреИрд╕реЗ рднрд┐рдиреНрди рд╣реЛрддреЗ рд╣реИрдВ

рдЙрд╕ рдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪреЗрдВ рдЬрд┐рд╕реЗ рдЖрдк рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд╕рднреА рдорд╛рд░реНрдЧреЛрдВ, рд╡рд┐рдЪрд╛рд░реЛрдВ рдФрд░ рдореЙрдбрд▓реЛрдВ рдХреЛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдврд╛рдВрдЪреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЖрдпрд╛рдд рдФрд░ рдЬреНрдЮрд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдпрд╣ рдПрдХ рдХрд╛рд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд╕рдорд╛рди рд╣реИ, рдЬрд┐рд╕реЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рдереА: рд╕рд░рд▓ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЬреИрд╕реЗ рд╣реЗрдбрд▓рд╛рдЗрдЯреНрд╕ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛, рдЖрдкрдХреЛ рдХрд╛рд░ рдореЗрдВ рдХрдВрдкреНрдпреВрдЯрд░ рдЪрд╛рд▓реВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

Django рдФрд░ рдлреНрд▓рд╛рд╕реНрдХ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ unittest- рдЖрдзрд╛рд░рд┐рдд рдкрд░реАрдХреНрд╖рдг рдврд╛рдВрдЪрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдирд╛ рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред



Django рдЯреЗрд╕реНрдЯ рдПрдХреНрд╕реЗрдХреНрдпреВрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ

Django рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдЯреЗрдореНрдкрд▓реЗрдЯ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ рдЯреЗрд╕реНрдЯрд╢реЛ рдлрд╛рдЗрд▓ рдмрдирд╛рддрд╛ рд╣реИред рдпрджрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╛рдордЧреНрд░рд┐рдпреЛрдВ рд╕реЗ рдмрдирд╛рдПрдБ:

from django.test import TestCase class MyTestCase(TestCase): # Your test methods 

рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рдореБрдЦреНрдп рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ django.test.TestCase рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рди рдХрд┐ unittest.TestCase ред рдЗрди рд╡рд░реНрдЧреЛрдВ рдХрд╛ API рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди Django TestCase рд╡рд░реНрдЧ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред

рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдкрд░ unittest рдХреЗ рдмрдЬрд╛рдп manage.py рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:

 $ python manage.py test 

рдЕрдЧрд░ рдЖрдкрдХреЛ рдХрдИ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдкрд░реАрдХреНрд╖рдг рдлрд╝реЛрд▓реНрдбрд░ рдХреЛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдлрд╝реЛрд▓реНрдбрд░ рд╕реЗ рдмрджрд▓реЗрдВ, рдЗрд╕рдореЗрдВ __init__.py рдирд╛рдордХ рдПрдХ рдЦрд╛рд▓реА рдлрд╝рд╛рдЗрд▓ рдбрд╛рд▓реЗрдВ рдФрд░ test_*.py рдлрд╝рд╛рдЗрд▓реЗрдВ рдмрдирд╛рдПрдБред Django рдЙрдиреНрд╣реЗрдВ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛ред

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА Django рдкреНрд░рд▓реЗрдЦрди рд╕рд╛рдЗрдЯ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред

рдпреВрдиреАрдЯреЗрд╕реНрдЯ рдФрд░ рдлреНрд▓рд╛рд╕реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ

рдлреНрд▓рд╛рд╕реНрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЖрд╡реЗрджрди рдХреЛ рдЖрдпрд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдкрд░реАрдХреНрд╖рдг рдореЛрдб рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдк рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЧреНрд░рд╛рд╣рдХ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдореЗрдВ рдХрд┐рд╕реА рднреА рдорд╛рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдкрд░реАрдХреНрд╖рдг рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдХреА рд╕реЗрдЯрдЕрдк рд╡рд┐рдзрд┐ рдореЗрдВ рддреБрд░рдВрдд рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, my_app рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛ рдирд╛рдо рд╣реИред рдЪрд┐рдВрддрд╛ рдордд рдХрд░реЛ рдЕрдЧрд░ рддреБрдо рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ setUp рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИред рд╣рдо "рдЕрдзрд┐рдХ рдЙрдиреНрдирдд рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдкрд┐рдпреЛрдВ" рдЕрдиреБрднрд╛рдЧ рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВрдЧреЗред
рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

 import my_app import unittest class MyTestCase(unittest.TestCase): def setUp(self): my_app.app.testing = True self.app = my_app.app.test_client() def test_home(self): result = self.app.get('/') # Make your assertions 

рдЖрдк рддрдм python -m unittest discover. рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдЯреЗрд╕реНрдЯ рдХреЗрд╕ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ python -m unittest discover.

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдлреНрд▓рд╛рд╕реНрдХ рдкреНрд░рд▓реЗрдЦрди рд╕рд╛рдЗрдЯ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред

рдЕрдзрд┐рдХ рдЙрдиреНрдирдд рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдкрд┐рдпреЛрдВ

рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ, рдХрд┐рд╕реА рднреА рдкрд░реАрдХреНрд╖рд╛ рдХреЗ рддреАрди рдореБрдЦреНрдп рдЪрд░рдгреЛрдВ рдХреЛ рдпрд╛рдж рд░рдЦреЗрдВ:

  1. рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг;
  2. рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди, рдЖрдЙрдЯрдкреБрдЯ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛;
  3. рдЕрдкреЗрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдо рдХреЗ рд╕рд╛рде рдЖрдЙрдЯрдкреБрдЯ рдбреЗрдЯрд╛ рдХреА рддреБрд▓рдирд╛;

рдпрд╣ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рд╕рдВрдЦреНрдпрд╛ рдЬреИрд╕реЗ рд╕реНрд░реЛрдд рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдерд┐рд░ рдореВрд▓реНрдп рдмрдирд╛рдиреЗ рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдХрднреА-рдХрднреА рдЖрдкрдХреЗ рдЖрд╡реЗрджрди рдХреЛ рдПрдХ рд╡рд░реНрдЧ рдпрд╛ рд╕рдВрджрд░реНрдн рдХреА рдПрдХ рдЖрд╡реГрддреНрддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ?

рд╕реНрд░реЛрдд рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдП рдЧрдП рдбреЗрдЯрд╛ рдХреЛ рдлрд╝рд┐рдХреНрдЪрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬреБрдбрд╝рдирд╛рд░ рдмрдирд╛рдирд╛ рдФрд░ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдПрдХ рдЖрдо рдмрд╛рдд рд╣реИред

рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рдХреА рдкреНрд░рддреНрдпрд╛рд╢рд╛ рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдкрд░реАрдХреНрд╖рдг рдХреЛ рдХрдИ рдмрд╛рд░ рдЪрд▓рд╛рдирд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЙрдореНрдореАрдж рдХреА рд╡рд┐рдлрд▓рддрд╛ рд╕реЗ рдирд┐рдкрдЯрдиреЗ

рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ, рдЬрдм рд╣рдордиреЗ рдкрд░реАрдХреНрд╖рдг sum() рд▓рд┐рдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдПрдХ рд╕реВрдЪреА рд╕рдВрдХрд▓рд┐рдд рдХреА рдереА, рддреЛ рд╕рд╡рд╛рд▓ рдЙрдарддрд╛ рдерд╛: рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рд╣рдо рдПрдХ рдЦрд░рд╛рдм рдореВрд▓реНрдп рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдПрдХрд▓ рдкреВрд░реНрдгрд╛рдВрдХ рдпрд╛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ?

рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдпрд╣ рдЙрдореНрдореАрдж рдХреА рдЬрд╛рддреА рд╣реИ рдХрд┐ sum() рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рджреЗрдЧреАред рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ, рддреЛ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЕрдкреЗрдХреНрд╖рд┐рдд рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рддрд░реАрдХрд╛ рд╣реИред рдЖрдк рдПрдХ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХ рдХреЗ рд░реВрдк рдореЗрдВ .assertRaises() рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд░рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 import unittest from my_sum import sum class TestSum(unittest.TestCase): def test_list_int(self): """ ,       """ data = [1, 2, 3] result = sum(data) self.assertEqual(result, 6) def test_list_fraction(self): """ ,       """ data = [Fraction(1, 4), Fraction(1, 4), Fraction(2, 5)] result = sum(data) self.assertEqual(result, 1) def test_bad_type(self): data = "banana" with self.assertRaises(TypeError): result = sum(data) if __name__ == '__main__': unittest.main() 

рдпрд╣ рдЯреЗрд╕реНрдЯ рдХреЗрд╕ рддрднреА рдкрд╛рд╕ рд╣реЛрдЧрд╛, рдЬрдм sum(data) рдПрдХ рдЯрд╛рдЗрдк-рдЗрдпрд░рд░ рдлреЗрдВрдХрддрд╛ рд╣реИред рдЖрдк TypeError рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдкрд╡рд╛рдж рд╕реЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрд╡реЗрджрди рд╡реНрдпрд╡рд╣рд╛рд░ рдЕрд▓рдЧрд╛рд╡

рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рдЕрдВрддрд┐рдо рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреАред рд╡реЗ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рд░рди рдПрдХ рдЕрд▓рдЧ рдкрд░рд┐рдгрд╛рдо рдпрд╛ рдЗрд╕рд╕реЗ рднреА рдмрджрддрд░ рдкреИрджрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ - рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкреВрд░реЗ рдЖрд╡реЗрджрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рджреВрд╕рд░реЗ рдкрд░реАрдХреНрд╖рдг рдХреЛ рд╡рд┐рдлрд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИ!

рдмрд╣реБрдд рд╕рд╛рд░реЗ рджреБрд╖реНрдкреНрд░рднрд╛рд╡реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЖрд╡реЗрджрди рдХреЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рд░рд▓ рддрдХрдиреАрдХреЗрдВ рд╣реИрдВ:

  • рдПрдХрд▓ рдЙрддреНрддрд░рджрд╛рдпрд┐рддреНрд╡ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреЛрдб рд░реАрдлреИрдХреНрдЯрд░рд┐рдВрдЧ;
  • рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдХреЛ рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рддрд░реАрдХреЛрдВ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХрд╛ рдордЬрд╝рд╛рдХ рдХрд░рдирд╛;
  • рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рдЗрд╕ рдЯреБрдХрдбрд╝реЗ рдХреЗ рд▓рд┐рдП рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдмрдЬрд╛рдп рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред
  • рдпрджрд┐ рдЖрдк рдореЛрдХрд┐рдВрдЧ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдХреБрдЫ рдорд╣рд╛рди рдкрд╛рдпрдерди рд╕реАрдПрд▓рдЖрдИ рдкрд░реАрдХреНрд╖рдг рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ ред

рд▓реЗрдЦрди рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг

рдЕрдм рддрдХ, рд╣рдордиреЗ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдкрд░ рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рд╣реИред рдкреВрд░реНрд╡рд╛рдиреБрдорд╛рди рдФрд░ рд╕реНрдерд┐рд░ рдХреЛрдб рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рдПрдХ рд╢рд╛рдирджрд╛рд░ рддрд░реАрдХрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдВрдд рдореЗрдВ, рдЖрдкрдХреЗ рдЖрд╡реЗрджрди рдХреЛ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП!

рдХрдИ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╣рдпреЛрдЧ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЦрд░реАрджрд╛рд░ рдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ:

  • HTTP REST API рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ;
  • рдЕрдЬрдЧрд░ рдПрдкреАрдЖрдИ рдХреЙрд▓;
  • рд╡реЗрдм рд╕реЗрд╡рд╛ рдХреЙрд▓;
  • рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдЪрд▓рд╛рдПрдВред

рдЗрди рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг, рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░реНрд╕, рдирд┐рд╖реНрдкрд╛рджрди, рдЕрдиреБрдореЛрджрди рдХреЗ рдмрд╛рджред рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдПрдХ рд╕рд╛рде рдЕрдзрд┐рдХ рдШрдЯрдХреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╡реЗ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рджреБрд╖реНрдкреНрд░рднрд╛рд╡ рдкреИрджрд╛ рдХрд░реЗрдВрдЧреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдЬреБрдбрд╝рдирд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕, рдиреЗрдЯрд╡рд░реНрдХ рд╕реЙрдХреЗрдЯ рдпрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ред

рдЗрд╕рд▓рд┐рдП, рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдФрд░ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЬрд╛рддреА рд╣реИред рдПрдХреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдЬреБрдбрд╝рдирд╛рд░ рдмрдирд╛рдирд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛рдмреЗрд╕ рдпрд╛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рд╣рд░ рдмрд╛рд░ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдЪрд▓рд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЗрдХрд╛рдИ рдФрд░ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрд░реАрдХрд╛ рдЙрдиреНрд╣реЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдореЗрдВ рд░рдЦрдирд╛ рд╣реИред

project/
тФВ
тФЬтФАтФА my_app/
тФВ тФФтФАтФА __init__.py
тФВ
тФФтФАтФА tests/
|
тФЬтФАтФА unit/
| тФЬтФАтФА __init__.py
| тФФтФАтФА test_sum.py
|
тФФтФАтФА integration/
тФЬтФАтФА __init__.py
тФФтФАтФА test_integration.py


рдЖрдк рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рд╕реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдореВрд╣ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╕реНрд░реЛрдд рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛, -s рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдзреНрд╡рдЬ, рдкрд░реАрдХреНрд╖рдг рдпреБрдХреНрдд рдкрде рдХреЗ рд╕рд╛рде рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 $ python -m unittest discover -s tests/integration 

unittest рдкрд░реАрдХреНрд╖рдг / рдПрдХреАрдХрд░рдг рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд╕рднреА рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ред

рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдЙрдиреНрдореБрдЦ рдЕрдиреБрдкреНрд░рдпреЛрдЧ

рдХрдИ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдмреИрдХрдПрдВрдб рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореВрд▓реНрдпреЛрдВ рд╡рд╛рд▓реЗ рдбреЗрдЯрд╛рдмреЗрд╕ред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ 100 рд╕реЗ рдЕрдзрд┐рдХ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд╕рд╛рде рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рд╣реА рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╛ рдСрд░реНрдбрд░ рдкреГрд╖реНрда рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рд╕рд╛рдорд╛рди рдХреЗ рд╕рднреА рдирд╛рдо рдЬрд╛рдкрд╛рдиреА рдореЗрдВ рд╣реЛрдВред

рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдЙрдирдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдФрд░ рдкреВрд░реНрд╡рд╛рдиреБрдорд╛рдирд╢реАрд▓рддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рдкрд░реАрдХреНрд╖рдг рдЬреБрдбрд╝рдирд╛рд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░реЗрдВрдЧреЗред

рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдХреЛ рдЙрдирдХреЗ "рдкрд░реАрдХреНрд╖рдгрдиреАрдпрддрд╛" рдкрд░ рдЬреЛрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рдЕрдВрджрд░ рдлрд┐рдХреНрд╕реНрдЪрд░ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдлрд┐рд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдЖрдк рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣рд╛рдВ JSON рдлрд╝рд╛рдЗрд▓реЛрдВ рд╕реЗ рдорд┐рд▓рдХрд░ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

project/
тФВ
тФЬтФАтФА my_app/
тФВ тФФтФАтФА __init__.py
тФВ
тФФтФАтФА tests/
|
тФФтФАтФА unit/
| тФЬтФАтФА __init__.py
| тФФтФАтФА test_sum.py
|
тФФтФАтФА integration/
|
тФЬтФАтФА fixtures/
| тФЬтФАтФА test_basic.json
| тФФтФАтФА test_complex.json
|
тФЬтФАтФА __init__.py
тФФтФАтФА test_integration.py


рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдк рдПрдХ рдЬреНрдЮрд╛рдд рддрд░реАрдХреЗ рд╕реЗ рдлрд╝рд┐рдХреНрдЪрд░ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдЗрд╕ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрдИ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП .setUp () рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдЖрдк рдПрдХ рдкрд╛рдпрдерди рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХрдИ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдПрдХрддрд░рдлрд╛ рдкрд╛рдПрдВрдЧреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВрдЧреЗред рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

 import unittest class TestBasic(unittest.TestCase): def setUp(self): # Load test data self.app = App(database='fixtures/test_basic.json') def test_customer_count(self): self.assertEqual(len(self.app.customers), 100) def test_existence_of_customer(self): customer = self.app.get_customer(id=10) self.assertEqual(customer.name, "Org XYZ") self.assertEqual(customer.address, "10 Red Road, Reading") class TestComplexData(unittest.TestCase): def setUp(self): # load test data self.app = App(database='fixtures/test_complex.json') def test_customer_count(self): self.assertEqual(len(self.app.customers), 10000) def test_existence_of_customer(self): customer = self.app.get_customer(id=9999) self.assertEqual(customer.name, u"уГРуГКуГК") self.assertEqual(customer.address, "10 Red Road, Akihabara, Tokyo") if __name__ == '__main__': unittest.main() 

рдпрджрд┐ рдЖрдкрдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рджреВрд░рд╕реНрде рд╕реНрдерд╛рди рдЬреИрд╕реЗ рджреВрд░рд╕реНрде API рд╕реЗ рдбреЗрдЯрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рджреЛрд╣рд░рд╛рдП рдЬрд╛рдиреЗ рдпреЛрдЧреНрдп рд╣реИрдВред рдПрдкреАрдЖрдИ рдФрд░ рд╕рдВрдЪрд╛рд░ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд░рд╣реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдХрд╛рд░рдг рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рджреЗрд░реА рд╣реЛ рд╕рдХрддреА рд╣реИред рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рджреВрд░рд╕реНрде рдлрд┐рдХреНрд╕реНрдЪрд░ рдХреЛ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╡рд╛рдкрд╕ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЖрд╡реЗрджрди рдкрд░ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИред

requests рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдПрдХ рдирд┐рдГрд╢реБрд▓реНрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреИрдХреЗрдЬ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЬреБрдбрд╝рдирд╛рд░ рдмрдирд╛рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдкрд░реАрдХреНрд╖рдг рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рд╣реЗрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрдирдХреЗ GitHub рдкреГрд╖реНрда рдкрд░ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ ред

рдЕрдЧрд▓рд╛ рднрд╛рдЧ рдХрдИ рд╡рд╛рддрд╛рд╡рд░рдгреЛрдВ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдФрд░ рд╕реНрд╡рдЪрд╛рд▓рди рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реЛрдЧрд╛ред

рдЕрдВрдд

рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ / рдкреНрд░рд╢реНрди рд╣рдореЗрд╢рд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред рдпрд╣рд╛рдВ рдпрд╛ рдЦреБрд▓реЗ рджрд┐рди рд╕реНрдЯрд╛рд╕ рдкрд░ рдЬрд╛рдПрдВред

Source: https://habr.com/ru/post/hi433572/


All Articles