Przejdź do głównej zawartości

W ciemność

Ostatnio na naszym kanale Slackowym kolega polecił mi, żebym zmienił bibliotekę do unit testów na nowszą i częściej używaną. Zachęcał mnie do wybrania raczej biblioteki minitest. Rzeczywiście jest to biblioteka bardziej popularna i więcej może. Tylko ja z moją starą biblioteką test-unit nadal spełniam warunek numer 3 z przysięgi programisty:
3. Dostarczyć z każdą wersją aplikacji szybki, pewny i powtarzalny dowód, że każda część kodu działa tak jak powinna.
Jeżeli tak, to po co bić pianę? Jeżeli będę potrzebował większych możliwości w przyszłości rzeczywiście zmienię bibliotekę. Na razie postąpię według reguły KISS (nie komplikuj głuptasku).


Dopiszę kolejne wymaganie do naszej aplikacji. Klienci i Goście z IT mogą zasubskrybować Media. Mogą też wysłać swoją reklamę, która ukaże się cykliczne w medium proponowanym przez Media.

Do mojego pliku z testami dodałem nowy test, w którym oczekuję, że będę mógł dodać reklamę z telefonem do swojej firmy.

def test_if_it_possible_to_add_advertising                                                                                                                                                                                                 
    it_people = ItPeople.new                                                                                                                                                                                                                 
    media = Media.new                                                                                                                                                                                                                        
    media.add_advertising(it_people.telephone_numer);                                                                                                                                           
end

Zgodnie z drugim prawem TDD skoro mam błędy kompilacji ...

NoMethodError: undefined method `category' for #<Media:0x007fd3eefabaa8>

... muszę przerwać pisanie testu i dodaję kod produkcyjny. A więc teraz klasa ItPeople musi wyglądać tak:

class ItPeople

  attr_accessor :telephone_number

end

Przy czym attr_accessor dodaje zmienną do klasy z możliwością jej edycji i odczytu.

A klasa Media przybierze postać:


class Media

  attr_accessor :categories                                                                                                                                                                                                                  
                                                                                                                                                                                                                                             
  def add_advertising telephone_number                                                                                                                                                                                                       
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
end  

I tu muszę wspomnieć, że po nazwie metody, po spacji dajemy listę parametrów metody. Mogę dać nawiasy, ale nie muszę.

Teraz, ponieważ testy przechodzą przerywam pisanie kodu produkcyjnego. Ponieważ mam leciutką duplikację w testach w deklaracji obiektów zrobię refaktor.

Zamienię to:


require "test-unit"                                                                                                                                                                                                                          
require "./src/Client.rb"                                                                                                                                                                                                                    
require "./src/ItPeople.rb"                                                                                                                                                                                                                  
require "./src/Media.rb"                                                                                                                                                                                                                     
                                                                                                                                                                                                                                             
class FirstSmokeTestClass < Test::Unit::TestCase                                                                                                                                                                                             
                                                                                                                                                                                                                                             
  def test_if_this_test_framework_works                                                                                                                                                                                                      
                                                                                                                                                                                                                                             
    assert_equal(2, 1 + 1)                                                                                                                                                                                                                   
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def test_if_there_are_actors_of_that_tragedy                                                                                                                                                                                               
                                                                                                                                                                                                                                             
    client = Client.new                                                                                                                                                                                                                      
    it_people = ItPeople.new                                                                                                                                                                                                                 
    media = Media.new                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
    assert_not_nil(client);                                                                                                                                                                                                                  
    assert_not_nil(it_people);                                                                                                                                                                                                               
    assert_not_nil(media);                                                                                                                                                                                                                   
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def test_if_it_possible_to_add_advertising                                                                                                                                                                                                 
    it_people = ItPeople.new                                                                                                                                                                                                                 
    media = Media.new                                                                                                                                                                                                                        
    media.add_advertising(it_people.telephone_number);                                                                                                                                                                                       
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
end  


W to:


require "test-unit"                                                                                                                                                                                                                          
require "./src/Client.rb"                                                                                                                                                                                                                    
require "./src/ItPeople.rb"                                                                                                                                                                                                                  
require "./src/Media.rb"                                                                                                                                                                                                                     
                                                                                                                                                                                                                                             
class FirstSmokeTestClass < Test::Unit::TestCase                                                                                                                                                                                             
                                                                                                                                                                                                                                             
  def setup                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                             
    @client = Client.new                                                                                                                                                                                                                     
    @it_people = ItPeople.new                                                                                                                                                                                                                
    @media = Media.new                                                                                                                                                                                                                       
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
  def test_if_this_test_framework_works                                                                                                                                                                                                      
                                                                                                                                                                                                                                             
    assert_equal(2, 1 + 1)                                                                                                                                                                                                                   
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def test_if_there_are_actors_of_that_tragedy                                                                                                                                                                                               
                                                                                                                                                                                                                                             
    assert_not_nil(@client);                                                                                                                                                                                                                 
    assert_not_nil(@it_people);                                                                                                                                                                                                              
    assert_not_nil(@media);                                                                                                                                                                                                                  
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def test_if_it_possible_to_add_advertising                                                                                                                                                                                                 
                                                                                                                                                                                                                                             
     @media.add_advertising(@it_people.telephone_number);                                                                                                                                                                                    
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
end    

Dodaję metodę setup, która odpala się za każdym razem, gdy odpala się test.
Dodatkowo zamiast zmiennych lokalnych ustawiam zmienne klasowe, których używam w dwóch ostatnich testach.

Nie podoba mi się jeszcze, że wszystkie testy są w jednym pliku testowym. Przeniosę nowe testy do nowego pliku actors_tests.rb i zaktualizuję Rakefile.

Powinienem chyba utworzyć tak zwane jarzmo testowe:

coola@sv26 [/home/coola/dsp2017/xp-simulator]# touch ./test/all_tests.rb    

Z zawartością:

require 'test/unit/testsuite'                                                                                                                                                                                                                
require './test/smoke_test.rb'                                                                                                                                                                                                               
require './test/actors_tests.rb' 

Odkryłem przypadkiem, że wystarczy odpalić taki plik poleceniem ruby i wszystkie testy wystartują automatycznie.

No dobra, czyli Rakefile powinien teraz wyglądać tak:


task default: %w[test]                                                                                                                                                                                                                       
                                                                                                                                                                                                                                             
task :test do                                                                                                                                                                                                                                
  ruby "./test/all_tests.rb"                                                                                                                                                                                                                 
end 

Dalsze przypadki testowe dopiszę wkrótce.

Link do commita zmian tu: https://github.com/coola/xp-simulator/commit/56d56a37e1c46b571924cf3d640540e6d548cc63

Mam wrażenie, że krzywa wejścia w Ruby jest mimo wszystko stroma, błądzę po omacku, szukam konstrukcji znajomych z innych języków, czując pod skórą, że mimo wszystko warto.

"Zabierz Pan nas stąd, Panie Sulu" Kapitan James T. Kirk



Komentarze

Popularne posty z tego bloga

Kursy IT na Pluralsight. Dlaczego warto?

Bardzo sobie cenię kursy na Pluralsight. Mam wrażenie, że każdy kurs, który przeszedłem na tej platformie, w dużym stopniu podniósł moje zdolności. Wiem, dostęp do tej platformy nie jest tani, ale w mojej ocenie warty swojej ceny. To nie jest reklama, ale forma entuzjazmu jaki mam do tej formy samodoskonalenia. O to kilka punktów pokazujących ofertę tego serwisu i dlaczego warto skorzystać: Pluralsight to kursy z Javascript, C#, Java, Angular, Python, MySQL i wielu innych technologii i umiejętności. Kursy na Pluralsight w większości mają wyższą jakość niż te, które możemy znaleźć na przykład na YouTube. Są wyselekcjonowane, mają wysoką jakość dźwięku i obrazu. Często wgryzają się głęboko w dany problem daleko poza standardowe „Hello World” danej technologii. Twórcy Pluralsight to często osoby znane ze świata IT i konferencji branżowych, jak: Scott Hanselman, Microsoft John Somnez, SimpleProgrammer.com John Skeet, Google Pluralsight udostępnia funkcjonalność ścieżek – paths....

Bicie piany

Czy słyszałeś o tym gościu, który powiedział, że Object Oriented to przeżytek? No nie. Następny. Co powiedział? Opisał wszystkie obietnice OO, i jak żadna z nich tak naprawdę nigdy nie została spełniona i o tych wszystkich możliwościach OO, które kosztują więcej, niż są warte i że funkcjonalne programowanie jest lepsze i ... Phi. Tak słyszałem już to wcześniej. No, więc OO jest martwe, leży i kwiczy i możemy przejść dalej. Przejść dalej do czego? Co? No do NASTĘPNEJ WIELKIEJ RZECZY oczywiście. Aaaa, do tego. Czy wiesz już co to jest? Nie bałdzo, ale jestem podekscytowany na myśl o mikroserwisach; jaram się Elixirem; i słyszałem, że React jest fantastyczny; i ... Tak, tak. Bicie piany. Dałeś się nabrać na bicie piany. Co? Co masz na myśli. Przecież mamy takie wspaniałe czasy. Tak naprawdę postrzegam te czasy jako depresyjne. Ale dlaczego? Przecież co kilka dni wyskakują nowe wspaniałe technologie! Wspinamy się na coraz wyższe szczyty. Phi. To, co tak napraw...

Podstawy Programowania Funkcyjnego Epizod 1

O czym jest programowanie funkcyjne? Zakładam, że słyszałeś już kiedyś o programowaniu funkcyjnym. No cóż, któż nie słyszał? Wszyscy o tym gadają. Wychodzi dużo nowych języków funkcyjnych takich, jak Scala, F# i Clojure. Ludzie rozmawiają też o starszych językach jak Erlang, Haskell, ML i innych. A więc, o co w tym wszystkim chodzi? Dlaczego programowanie funkcyjne jest Następną Wielką Rzeczą™? I co jest w tym takiego pociągającego? Poniższy tekst jest luźnym tłumaczeniem wpisu bloga Roberta Cecila "Wujka Boba" Martina z dnia 22 grudnia 2012 ze strony: https://blog.cleancoder.com/uncle-bob/2012/12/22/FPBE1-Whats-it-all-about.html Proszę o komentarze, jeżeli ta luźność jest zbyt daleko posunięta. Po pierwsze, prawie na pewno programowanie funkcyjne jest następną wielką rzeczą. Są ku temu dobre, solidne powody i poznamy je w tym artykule. Ale najpierw, aby zrozumieć te powody, musimy poznać, czym programowanie funkcyjne jest....