AAA (Arrange, Act, Assert) Pattern Kullanarak Test Yazmak

Tuğsan Ünlü
Akbank Teknoloji
Published in
4 min readMar 16, 2023

--

Motivasyon

Bir uygulamanın veya uygulama parçasının hangi özelliklerine test yazılacağı ve bu testler yazılırken nasıl bir yol izleneceği özellikle test yazmaya yeni başlayan yazılım ve QA (Quality Assurance) geliştiricilerin zihnini en çok kurcalayan sorulardan biridir. Yazılan test ister bir birim isterse de uçtan uca bir test senaryosu olsun, AAA Pattern ile önceliklendirilmemiş ve metodoloji seçimi yapılmadan yazılmış testler, çoğu zaman kendi içerisinde doğru şekilde çalışsa dahi uygulamanın doğru şekilde çalışıp çalışmadığıyla ilgili kesin cevap veremezler. Peki, test aşaması için çok önemli olan bu AAA Pattern nedir? Gelin, birlikte göz atalım.

AAA (Arrange, Act, Assert) Pattern

Tüm yazılım problemlerinde olduğu gibi test aşamasında da bir design pattern’e başvurmak en doğru yoldur. Bilindiği üzere design pattern’ler, yaygın sorunların çözümleri hakkında bir başvuru kılavuzu olarak kullanılırlar. AAA pattern (3A veya Triple A olarak da adlandırılır) de test yazarken başvuracağımız bir design pattern’dir. Arrange, Act ve Assert kelimelerinin baş harflerinden oluşan bu pattern, bir test senaryosunu anatomik olarak üç ana parçaya ayırarak yönetmeyi önerir.

Arrange

Arrange yani “hazırlık” bölümü, test senaryosu içerisinde ihtiyaç duyulacak fonksiyon ve verilerin tanımlandığı bölümdür. Bir test dosyasını, uygulama parçalarından ayrıştırılmış bir ortam olarak düşünelim; Arrange bölümünü, test dosyasının dış dünyayla iletişim kurduğu, uygulamanın gerekli noktalarına eriştiği ve bu noktalarla birtakım veriler paylaştığı bölümü olarak görebiliriz.

Act

Act yani “eylem” bölümü, bir önceki arrange adımında hazırlığı yapılan test ortamıyla kullanıcıların etkileşime geçtiği bölümdür. Bu bölümde uygulamanın özellikleri göz önünde bulundurularak farklı farklı birçok son kullanıcı etkileşimi senaryosu test edilebilir. Kullanıcının bir butona tıklaması, bir input’a veri girişi yapması veya bir sayfadan çıkıp başka bir sayfaya giriş yapması act bölümünde ele alınarak test edilir.

Assert

Assert yani “iddia” bölümü ise arrange bölümünde hazırlığı yapılan, act bölümünde etkileşime geçilen uygulamanın, bu adımların sonucunda nasıl bir davranış göstereceğine dair iddialarımızın yer aldığı bölümdür. Bir test senaryosunun başarılı veya başarısız olduğuna, bu bölümdeki iddianın gerçekleşip gerçekleşmemesine göre karar verilir. Sonuç olarak, doğru şekilde yazılmış her test senaryosunun en az bir iddia içermesi gerekir.

Örnek Testler

Haydi şimdi, popüler test kütüphanelerinden React Testing Library kullanılarak yazılmış bir unit test ve Cypress kullanılarak yazılmış bir uçtan uca test senaryosu üzerinde AAA pattern’in uygulama pratiklerini inceleyelim.

test('show textfield error', () => {
// arrange
render(<Textfield maxLength="3" data-testid="textfield" />)

// act
fireEvent.change(screen.getByTestId('textfield'), { target: { value: 'foobar' } });

// assert
expect(screen.getByText('Input should not be more than 3 characters')).toBeInDocument()
expect(screen.getByTestId('textfield')).toHaveValue("foo")
})

Üstteki örneğin arrange bölümünde, daha önce yazılmış Textfield isimli bir React component’i maxLength ve testId değerleriyle birlikte React Testing Library kütüphanesinin render metodu aracılığıyla render ediliyor. Akabinde act bölümünde Textfield component’inin sağladığı input’a, maxLength ile tanımlanan değerden fazla sayıda karaktere sahip bir metin girişi yapılıyor. Son olarak assert bölümünde ise girilen değerin karakter sayısının, maxLength ile tanımlanan maksimum karakter sayısını aştığı bilgisinin kullanıcıya gösterildiği ve kullanıcının girdiği metnin izin verilen kadarının input içerisine yazılıp kalanının göz ardı edildiği iddia ediliyor.

it('show login error', () => {
// arrange
cy.visit('https://foo.bar/login')

// act
cy.get('button').contains('Exist user').click()
cy.get('input[type="email"]').type('foo@bar.com')
cy.get('input[type="password"]').type('foobar')
cy.get('button').contains('Login').click()

// assert
cy.contains('The username or password is incorrect').should('be.visible')
})

Cypress kütüphanesi kullanılarak yazılan diğer örnekte ise arrange bölümünde bir web uygulamasının kullanıcı giriş sayfası açılıyor. Akabinde act bölümünde rastgele yazılmış bir e-posta adresi ve parolayla giriş formu doldurulup gönderiliyor. Assert bölümünde ise bu bilgilerin hatalı olduğu mesajının ekranda son kullanıcıya gösterildiği iddia ediliyor.

Sonuç

AAA pattern kullanılırken act bölümündeki etkileşimler değişip çeşitlendikçe assert bölümündeki iddiaların da değişmesi gerekir. Bu sayede yazılan testlerin happy path, golden path veya sunny day olarak adlandırılan, yalnızca normal şartlarda gerçekleşmesi beklenen, sonuçları tahmin edilen senaryoları içermesinin önüne geçilebilir.

Konuyu özetlemek gerekirse; React Testing Library kütüphanesi kullanılarak yazılan unit test örneğinde, Textfield component’i, input’a maxLength ile tanımlanan değerden az veya eşit karakter sayısına sahip bir metin girişi yapıldığında farklı bir davranış gösterecekti. Yine benzer şekilde, Cypress kütüphanesi kullanılarak yazılan uçtan uca test örneğinde, kullanıcı giriş bilgileri forma doğru şekilde girildiğinde uygulama bambaşka bir arayüzle çalışmasına devam edecekti. Bu davranışları birbirinden bağımsız çalışacak şekilde ayrı ayrı ele almak, code / behavioral coverage olarak adlandırılan uygulamanın test kapsamını genişletecek ve uygulama içerisinde gerçekleşmesi ihtimal olan daha fazla durumu kontrol altına alacaktır.

Kullanıcı deneyimi (UX) süreçlerinde, kullanıcı hikâyeleri (user story) önemli bir yer tutar ve her kullanıcının kendine has bir kullanım senaryosu olduğu fikri benimsenir. Bir uygulama parçası geliştirilirken belli bir amaca yönelik geliştirilse de son kullanıcı o amaca ulaşana kadar başarılı olup olmamasından bağımsız olarak birden fazla yolu deneyebilir. O yüzden yazdığımız testlerdeki act bölümlerini ne kadar çeşitlendirirsek o kadar çok kullanım senaryosuna temas etmiş ve uygulamanın o kadar çok farklı noktasını test etmiş oluruz.

Kaynaklar

--

--