Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python ve birim testleri

Emre Yılmaz
February 01, 2017

Python ve birim testleri

Emre Yılmaz

February 01, 2017
Tweet

More Decks by Emre Yılmaz

Other Decks in Programming

Transcript

  1. BİRİM TESTLERİ ▸ Kodun belirli bölümlerini -birimlerini- test eden/çalıştıran kod

    bütünü. ▸ Doğası gereği hiçbir bağımlılığı olamaz. ▸ unit (birim), bir uygulamanın test edilebilir en küçük parçacığını ifade eder. Bu bir fonksiyon, sınıf, metod olabilir.)
  2. “WHENEVER YOU ARE TEMPTED TO TYPE SOMETHING INTO A PRINT

    STATEMENT OR A DEBUGGER EXPRESSION, WRITE IT AS A TEST INSTEAD.” Martin Fowler BİRİM TESTLERİ
  3. NE ZAMAN UNİT TEST OLMAZ? ▸ Test, çalışmak için kendinden

    daha büyük bir şeye ihtiyaç duyuyorsa “birim” test olmaktan çıkar.
 ▸ Örneğin, test çalışmak için 3. parti bir API çıktısına ihtiyaç duyuyorsa bu bir “entegrasyon testi” olur. ▸ Ya da tüm bir uygulama belirli kurallara göre, birbirine bağımlı senaryolarla test ediliyorsa “acceptance” test olur.
  4. BİRİM TESTLERİ NE İŞİMİZE YARAR? ▸ Geliştirme sırasında hataları tespit

    edebilmek için. ▸ Kodun tasarımı için bir araç. (TDD* ile kodlamadan önce dizayn etmek şart.) ▸ Bakımı yapılabilir kod geliştirmek için şart. ▸ * TDD: Test Driven Development (Test Güdümlü Programlama.)
  5. BİRİM TESTLERİ NE İŞİMİZE YARAR? ▸ Uygulamanın sorunsuz çalıştığını garanti

    etmez. Her birim sorunsuz çalışıyor ve tüm testler %100 coverage ile geçiyor olabilir, ama bu birimler bir arada doğru çalışmıyor olabilir. ▸ Testleri de yazan insanlar olduğu için ve insanlar her problemli durumu düşünemediği için %100 bug-free bir yazılım garanti etmez ama içiniz rahat, temiz, bakımı yapılabilir bir kod tabanı vaat eder.
  6. BEST PRACTICES ▸ Tek seferde tek birim test edin. ▸

    Her test kendi içinde bağımsız olmalı. Diğer testlerle ‘state’ paylaşmamalı. ▸ External servisler ve bağımlılıklar mock’lanmalı. ▸ Her test’in ismi, test ettiği birimi açıklamalı. ▸ Yazdığınız kod test edilebilir olmalı. (Django request’i kullanan bir metodu test etmek zor.)
  7. HIZLI BİR BAŞLANGIÇ ▸ pytest kütüphanesi ▸ Standart kütüphanedeki unittest

    modülünden daha rahat ve basit bir kütüphane. ▸ Sadece assert ile birim testi ihtiyaçlarının büyük kısmını karşılayabilirsiniz. (assertBilmemne ezberlemenize gerek yok.) ▸ kurulum: pip install pytest
  8. İLK TESTİMİZİ YAZALIM ▸ Bir iş görüşmesinde “palindrome” ne anlama

    gelir anlatıldı. Bir string’in palindrome olup olmadığını anlayan ve duruma göre True/False dönen bir fonksiyon yazmanız istendi.
 ▸ def is_palindrome(text):
 return True/False
  9. CODE COVERAGE ▸ Birim testlerin, test edilen modülün ne kadarını

    karşıladığını belirten bir ölçüm. Genelde yüzdelik dilimlerle ifade edilir. (%77 gibi.) ▸ pip install pytest-cov
 

  10. WORKSHOP ▸ Verilen numaranın asal olup olmadığını söyleyen basit bir

    fonksiyon: is_prime
 
 def is_prime(number):
 """
 Checks a number is a prime or not.
 Returns bool.
 """
 if number < 2:
 return False
 for i in range(2, number):
 if number % i == 0:
 return False
 
 return True

  11. WORKSHOP ▸ Atölye: ▸ https://github.com/metglobal/python-unit-testing- workshop/tree/master/solutions/prime_number ▸ deposunu yerelinize çekip

    testlerini yazıp pull request açınız. testlerinizi barındıran dosya, tests_ad_soyad.py şeklinde olmalıdır.

  12. MOCKING (SAHTE NESNELER YARATMA) ▸ external objeler, metodları taklit eden,

    onlar gibi davranan objeler yaratmak mümkün. ▸ metodun dönüş değeri, ne kadar saniye süreceği dahil her şey kontrol edilebilir. ▸ pip install mock (py3k’da standart kütüphanede var.) ▸ from mock import MagicMock
 reservation = MagicMock()
 reservation.cancel.return_value = 'cancelled'
 print reservation.cancel(booking_id='x', ref_no=15)
  13. LET’S PATCH ALL THE THINGS! ▸ External bağımlılıkları mock objeleriyle

    patchleyip unit-test’ler çalışırken dışa olan bu bağımlılığı ‘mock’layabiliriz. ▸ Hem birim testler hızlı çalışır, hem de hakikaten ‘birim’ test yapmış oluruz. Mesela, kodun bir aşamasında requests kütüphanesiyle bir API sistemine istek atılıyor diyelim. ▸ pip install pytest-mock ▸ def test_api(mocker):
 mocked_get = mocker.patch.object(requests, 'get')
 mocked_get.return_value.text = "NOTOK"
 response_text = requests.get(‘https://api2.hotelspro.com/api/v2/ping').text
 assert '"Ok"' == response_text