Mühendisler olarak işe yarayan şeyler oluşturmak istiyoruz, ancak yarattığımız her yeni özellik ile kaçınılmaz olarak uygulamalarımızın boyutunu ve karmaşıklığını artırıyoruz.
Ürün büyüdükçe, değişikliklerinizden etkilenen her işlevi manuel olarak (örneğin ellerinizle) test etmek giderek daha fazla zaman alır.
Otomatik testlerin yokluğu ya çok fazla zaman harcamamıza ve sevkıyat hızımızı yavaşlatmamıza ya da hızı korumak için çok az harcamamıza yol açıyor, bu da PagerDuty'den gece geç saatlerde yapılan çağrılarla birlikte biriktirilen işlerde yeni hatalara yol açıyor.
Tam tersine, bilgisayarlar aynı şeyi tekrar tekrar yapacak şekilde programlanabilir . O halde testi bilgisayarlara devredelim!
Test piramidi fikri üç ana test türünü önerir: birim, entegrasyon ve uçtan uca . Her türe derinlemesine dalalım ve her birine neden ihtiyacımız olduğunu anlayalım.
Birim , ayrı ayrı (diğer bileşenlere güvenmeden) test ettiğiniz küçük bir mantık parçasıdır.
Birim testleri hızlıdır. Saniyeler içinde bitiriyorlar. Yalıtım , bağımlı hizmetleri çalıştırmadan/API ve veritabanı çağrıları yapmadan bunları herhangi bir zamanda yerel olarak ve CI üzerinde çalıştırmalarına olanak tanır.
Birim testi örneği: İki sayıyı kabul eden ve bunları toplayan bir fonksiyon. Bunu farklı argümanlarla çağırmak ve döndürülen değerin doğru olduğunu iddia etmek istiyoruz.
// Function "sum" is the unit const sum = (x, y) => x + y test('sums numbers', () => { // Call the function, record the result const result = sum(1, 2); // Assert the result expect(result).toBe(3) }) test('sums numbers', () => { // Call the function, record the result const result = sum(5, 10); // Assert the result expect(result).toBe(15) })
Daha ilginç bir örnek, API isteği bittikten sonra bazı metinleri işleyen React bileşenidir. Testlerimiz için gerekli değerleri döndürmek, bileşeni oluşturmak ve oluşturulan HTML'nin ihtiyacımız olan içeriğe sahip olduğunu iddia etmek için API modülünü taklit etmemiz gerekiyor.
// "MyComponent" is the unit const MyComponent = () => { const { isLoading } = apiModule.useSomeApiCall(); return isLoading ? <div>Loading...</div> : <div>Hello world</div> } test('renders loading spinner when loading', () => { // Mocking the API module, so that it returns the value we need jest.mock(apiModule).mockReturnValue(() => ({ useSomeApiCall: jest.fn(() => ({ // Return "isLoading: false" for this test case isLoading: false })) })) // Execute the unit (render the component) const result = render(<MyComponent />) // Assert the result result.findByText('Loading...').toBeInTheDocument() }) test('renders text content when not loading', () => { // Mocking the API module jest.mock(apiModule).mockReturnValue(() => ({ useSomeApiCall: jest.fn(() => ({ // Return "isLoading: false" for this test case isLoading: false })) })) // Execute the unit (render the component) const result = render(<MyComponent />) // Assert the result result.findByText('Hello world').toBeInTheDocument() })
Biriminiz diğer birimlerle (bağımlılıklar) etkileşime girdiğinde buna entegrasyon diyoruz. Bu testler birim testlerinden daha yavaştır ancak uygulamanızın bölümlerinin nasıl bağlandığını test ederler.
Entegrasyon testi örneği: Bir veritabanında kullanıcılar oluşturan bir hizmet. Bu, testler yürütüldüğünde bir veritabanı örneğinin ( bağımlılık ) mevcut olmasını gerektirir. Hizmetin DB'den bir kullanıcı oluşturup alabildiğini test edeceğiz.
import db from 'db' // We will be testing "createUser" and "getUser" const createUser = name => db.createUser(name) // creates a user const getUser = name => db.getUserOrNull(name) // retrieves a user or null test("creates and retrieves users", () => { // Try to get a user that doesn't exist, assert Null is returned const nonExistingUser = getUser("i don't exist") expect(nonExistingUser).toBe(null); // Create a user const userName = "test-user" createUser(userName); // Get the user that was just created, assert it's not Null const user = getUser(userName); expect(user).to.not.be(null) })
Bu, tüm bağımlılıklarının mevcut olduğu, tam olarak konuşlandırılmış uygulamayı test ettiğimiz uçtan uca bir testtir. Bu testler, gerçek kullanıcı davranışını en iyi şekilde simüle eder ve uygulamanızdaki olası tüm sorunları yakalamanıza olanak tanır, ancak bunlar en yavaş test türüdür.
Uçtan uca testler gerçekleştirmek istediğinizde tüm altyapıyı sağlamalı ve ortamınızda 3. taraf sağlayıcıların bulunduğundan emin olmalısınız.
Bunlara yalnızca uygulamanızın kritik görev özellikleri için sahip olmak istersiniz.
Uçtan uca bir test örneğine bakalım: Oturum açma akışı. Uygulamaya gitmek, giriş bilgilerini doldurmak, göndermek ve hoş geldiniz mesajını görmek istiyoruz.
test('user can log in', () => { // Visit the login page page.goto('https://example.com/login'); // Fill in the login form page.fill('#username', 'john'); page.fill('#password', 'some-password'); // Click the login button page.click('#login-button'); // Assert the welcome message is visible page.assertTextVisible('Welcome, John!') })
Uçtan uca testlerin entegrasyondan , entegrasyon testlerinin ise birim testlerden daha yavaş olduğunu unutmayın.
Üzerinde çalıştığınız özellik kritik bir görevse, en az bir uçtan uca test yazmayı düşünün (Kimlik Doğrulama akışını geliştirirken Oturum Açma işlevinin nasıl çalıştığını kontrol etmek gibi).
Görev açısından kritik akışların yanı sıra, mümkün olduğunca çok sayıda uç durumu ve özelliğin çeşitli durumlarını test etmek istiyoruz. Entegrasyon testleri, uygulamanın parçalarının birlikte nasıl çalıştığını test etmemizi sağlar.
Uç noktalar ve istemci bileşenleri için entegrasyon testlerinin yapılması iyi bir fikirdir. Uç noktaların işlemleri gerçekleştirmesi, beklenen sonucu üretmesi ve beklenmeyen hatalar vermemesi gerekir.
İstemci bileşenleri doğru içeriği görüntülemeli ve kullanıcı etkileşimlerine, onlardan beklediğiniz şekilde yanıt vermelidir.
Ve son olarak birim testlerini ne zaman seçmeliyiz? Sayıları toplayan sum
, <button>
etiketini oluşturan Button
gibi ayrı ayrı test edilebilecek tüm küçük işlevler, birim testleri için mükemmel adaylardır. Test Odaklı Geliştirme yaklaşımını izlerseniz birimler mükemmeldir.
Bazı testler yazın! (ama küçük başlayın)
Nasıl çalıştığını anlamak için yukarıdaki işlemleri bir kez yapın. Daha sonra bazı özellik/hata çalışmaları sırasında bunu tekrar yapın. Daha sonra bunu iş arkadaşlarınızla paylaşın, böylece hepiniz testler yazabilir, zamandan tasarruf edebilir ve geceleri daha iyi uyuyabilirsiniz!