JMeter İle Performans Testi

Ceyhun Erdil
Ford Otosan
Published in
9 min readNov 17, 2023
https://blog.onesaitplatform.com/en/2022/06/20/jmeter-good-practices/
https://blog.onesaitplatform.com/en/2022/06/20/jmeter-good-practices/

Performans testi nedir?

Performans, bir uygulamanın bir operasyonu ne kadar hızlı gerçekleştirdiği olarak tanımlanabilir. Tek bir işlem gönderilerek uygulamanın performans çıktısı elde edilebilir. Fakat bu yöntem ile uygulamanın performansı hakkında yeterli bilgi edinmek neredeyse imkansızdır. Uygulamayı belirli bir yük ile test etmek çok daha doğru çıktılar üretecektir. Belirlenen bir yük ile (bir servise saniyede 10 istek gönderilmesi gibi) belirli bir süre (toplamda 120 saniye testin devam etmesi gibi) boyunca yapılan teste ise yük testi denilmekte.

Yük testi sayesinde uygulamamızın performansını ölçebilir, farklı uygulamalarla performans karşılaştırmasını yapabilir ve en önemlisi uygulamamızda yer alan darboğazları (bottlenecks) belirleyebiliriz. Test süresince sunucular, veri tabanları ve network izlenerek detaylı performans ölçümleri yapılabilir. Performans testlerinde uygulama hatalarından kaynaklı etkilerden kaçınmak için öncesinde mutlaka fonksiyonalite testleri yapılmalıdır. Ayrıca performans testi öncesinde smoke test yapılarak test senaryosunun doğru çalıştığı kontrol edilmelidir.

Performans testleri sayesinde uygulamamızın

  • Response time (uygulamaya gönderilen bir isteğe karşılık ne kadar zamanda cevap alındığı),
  • Throughput (belirli bir sürede başarılı tamamlanan istek sayısı),
  • Reliability (uygulamanın belirli bir süre boyunca verilen çevresel koşullar altında çalışma yeteneği),
  • Scalability (uygulamanın artan talebi büyütme ve yönetme yeteneği)

durumlarını gözlemleyebiliriz.

JMeter

Apache tarafından java tabanlı geliştirilmiş, performans testleri yapılmasına olanak sağlayan %100 açık kaynak kodlu test uygulamasıdır. Multi-thread olarak çalışan, bir çok protokolü destekleyen ve karmaşık test senaryoları gerçekleştirmemize olanak sağlayan performans test aracıdır. Başlangıçta web uygulama testleri için geliştirilmiş, zamanla yapılan değişiklerle birlikte farklı test türleri de eklenmiştir. Statik ve dinamik kaynakların test edilmesine olanak sağlar. Web, LDAP, mail server gibi farklı türlerde servis ve protokol tipleri test edilebilir.

JMeter sayesinde farklı yük türleri ile test yapabilir ve çıktılar elde edebiliriz. Test senaryosu her kullanıcı için oluşturulan thread’ler aracılığı ile gerçekleştirilir. Test senaryolarının dinamik olarak yapılandırılabilmesi sebebiyle farklı türde performans testleri gerçekleştirilebilir.

Gerçekleştirilebilecek test türleri aşağıdaki gibidir.

  • Smoke Test: Test senaryosunun doğru çalıştığını teyit etmek için genelde tek bir istek ile yapılan test.
  • Load Test: Belirli bir yük ile yapılan test. Uygulamamızın performans sınırını ölçebiliriz.
  • Stress Test: Uygulamanın kaldırabileceğinden çok daha fazla yük ile yapılan test. Bu test sayesinde uygulamamızın hangi seviyeye kadar cevap verebileceğini görebiliriz.
  • Spike Test: Ani yük değişimleri ile yapılan test. Ani yük değişimleri arasında uygulamamızın nasıl tepki verdiğini görebiliriz.
  • Endurance Test: Uygulamanın kaldırabileceği yük ile uzun süreler boyunca (saat veya gün) yapılan test. Uygulamamızda hafıza sızıntısı (memory leak), açık veri tabanı bağlantısı kalması gibi sorunları belirleyebiliriz.

Testlerin genel akışında her kullanıcı için bir thread oluşturulur. Senaryoda tanımlanan istek hazırlanır ve oluşturulan thread ile sunucuya gönderilir. JMeter sunucudan gelen cevabı kaydeder, bu cevaplar üzerinden ölçümler için gerekli verileri toplar. Toplanan veriler kullanılarak raporlar ve grafikler oluşturulur. Bu akış test senaryosunda belirtilen kez gerçekleştirilir. Çalışma mantığı basitçe bu şekilde açıklanabilir.

JMeter bileşenleri

JMeter testlerini yapboz olarak düşünebiliriz. İstediğimiz fonksiyonları yapboz parçaları olarak düşündüğümüzde gerekli parçaları test planımıza ekleyerek kurguladığımız teste ulaşabiliriz. Bu özelliği ile testlerimiz oldukça modüler bir yapıya sahip olacaktır, istediğimiz zaman ihtiyacımız olan fonksiyonları test senaryosuna kolayca ekleyip çıkartabiliriz.

İstediğimiz fonksiyonaliteyi sağlayan yapboz parçalarını bileşenler olarak tanımlayabiliriz. Test bileşenleri ağaç yapısında organize edilmiştir. Her bileşen ağaç yapısına göre üstünde yer alan bileşene/bileşenlere etki edebilir. Hiyerarşi olarak her test için ağaç yapısının en üstünde Test Plan bileşeni olmak zorundadır. Direkt veya dolaylı yoldan diğer tüm bileşenler Test Plan bileşenine bağlıdır.

Test senaryolarını oluşturmak, senaryoları veri ile beslemek ve senaryo sonuçlarını anlamlandırmak için kullanılan bir çok bileşen JMeter tarafından sunulmaktadır. Bu bileşenlerden en sık kullanılanlar aşağıdaki gibidir.

Temel Bileşenler

  • User Defined Variables: Test süresince tüm thread’lere uygulanacak varsayılan değerler tanımlanır.
  • HTTP(S) Test Script Recorder: Browser üzerinden yapılan işlemlerin kaydedilmesini sağlayan proxy server. Bu bileşen sayesinde test senaryolarımızı kolaylıkla oluşturabiliriz.
  • Thread Group: Test senaryosunu çalıştırmak için kullanılacak değerler (kullanıcı sayısı, testin kaç kere gerçekleştirileceği gibi) bu bileşen ile eklenir.

Config Element

Test senaryosunda kullanılacak konfigürasyon değerlerini tanımladığımız bileşenlerdir.

  • CSV Data Set Config: Test senaryolarında farklı değerler kullanılmasını sağlayan kaynak dosya tanımlanır. Kaynak dosyadan alınan değerlerin JMeter içerisinde kullanılacak olan parametre isimleri atanır.
  • HTTP Header Manager: Testlere uygulanacak ortak varsayılan header tanımları yapılır.
  • HTTP Cookie Manager: Testlere uygulanacak ortak varsayılan cookie tanımı yapılır.
  • HTTP Cache Manager: Testlere uygulanacak ortak varsayılan cache tanımı yapılır.
  • HTTP Request Defaults: Testlere uygulanacak ortak varsayılan http istek seçenekleri tanımlanır.

Listener

Test senaryo sonuçlarından toplanacak verileri yakalayan bileşenlerdir.

  • View Results Tree: Test bazında sonuçların gösterildiği bileşen.
  • Summary Report: Tüm test sonuçlarının anlamlı veriye dönüştürülerek gösterildiği bileşen.
  • Aggregate Report: Median gibi farklı parametrelerin sağlandığı, summary report benzeri bileşen.
  • Backend Listener: Test sonuçlarının dış kaynağa (csv dosyası, web servis gibi) kaydedilmesini sağlayan bileşen.

Jmeter tarafından sunulan varsayılan bileşenlerin yetersiz gelmesi durumunda custom plugin’ler ile ekstra bileşenler uygulamaya eklenebilmektir. https://jmeter-plugins.org/ adresinden plugin listesine ve plugin açıklamalarına ulaşılabilir.

JMeter kurulum

JMeter testlerini gerçekleştirmek için çok güçlü bilgisayarlara ihtiyacımız yoktur. Ortalama kişisel bilgisayar ile testler çalıştırılabilir. Testleri çalıştırmak için 4 veya daha fazla çekirdeğe sahip 16 GB RAM bulunan bir bilgisayar ideal olacaktır.

JMeter Java ile oluşturulmuş bir araç olduğu için Java Sanal Makinesi (JVM) yüklü olan herhangi bir işletim sistemi üzerinde çalıştırılabilmektedir. JRE ve JDK içerisinde JVM bulunmaktadır. JMeter içerisinde gelen bazı özellikler JDK desteğine ihtiyaç duymaktadır bu yüzden JDK kullanılması beklenmedik durumların önüne geçecektir. Kullanılacak JMeter versiyonları için farklı java versiyonlarına ihtiyaç duyulmaktadır. Bu sebeple versiyon uyumluluk kontrolü mutlaka yapılmalıdır.

Örneğimizde JMeter 5.5 versiyonu kullandık, bu versiyon Java 8+ gerektirmektedir. JMeter kurulmadan önce testleri yapacağınız ortamda Java 8+ versiyonun kurulu olduğu kontrol edilmelidir. Kurulumu gerçekleştirmek için JMeter sitesinden ZIP/TGZ dosyasını indirmeli ve JMeter’ı kullanmak istediğiniz dizine bu dosyayı çıkartmanız yeterli. Çıkartılan dizinde aşağıdaki dosyalar yer almaktadır.

apache-jmeter-X.Y.Z

  • bin: JMeter’ı çalıştıran script’lerin yer aldığı klasör. Klasör içerisinde ayrıca örnek ve template’ler yer almaktadır.
  • docs: Kullanıcı rehberleri yer alır.
  • extras: Yardımcı tool’lar yer alır.
  • lib: JMeter’ın çalışması için gerekli olan dosyalar yer alır.
  • licenses: Apache’ye ait olmayan üçüncü parti yazılım lisansların yer aldığı klasör.
  • printable_docs: Çıktı olarak alınabilen JMeter dokümanlarının yer aldığı klasör.

Örneğimizde Windows 10 işletim sistemi kullanıldığı için bin klasörünün altında yer alan “jmeter.bat” dosyasının çalıştırılması ile uygulamamızın ara yüzüne erişebiliriz. Daha önce oluşturulmuş bir test dosyasını çalıştırmak için ara yüz dışında komut satırı da kullanabilir. “jmeter -n -t testFile.jmx” komutu çalıştırılarak test senaryosunun gerçekleştirilmesi sağlanabilir. Jmeter test senaryoları xml formatında jmx uzantısı ile kaydedilir.

Test planı oluşturma

Bu kısımda uygulamalı olarak bir test senaryosu oluşturacağız. Testi çalıştırdıktan sonra sonuçları inceleyeceğiz. Önceden hazırladığımız api endpoint’e yük testi uygulayacağız. Bu endpoint ile eriştiğimiz servis gönderilen veriler ile veri tabanında güncelleme işlemi yapacak. Servisimizin bağlı olduğu tabloda gönderdiğimiz identifier’a ait kayıt varsa gönderdiğimiz değer ile ilgili kaydı güncelleyecek. Identifier’ları dinamik olarak bir veri kaynağından çekerek isteklerimize ekleyeceğiz. Testimizi 60 saniye sürecek ve toplam 600 kullanıcı ile çalışacak şekilde yapılandıracağız.

Test Plan, bir testin kök elementidir. Tüm ayarların yapıldığı ve test ile ilgili tüm diğer bileşenleri içeren temel elementtir. JMeter’a yeni bir test eklediğinizde varsayılan olarak eklenecektir.

“File” -> “New” ile yeni bir test plan oluşturuyoruz.

Oluşturduğumuz kök element ağaç yapısında en üstte yer alır. Bundan sonra ekleyeceğimiz tüm bileşenleri bu Test Plan elementine veya Test Plan elementine ait child elementlere ekleyeceğiz.

Test Plan’a sağ tıklayarak “Add” -> “Threads (User)” -> “Thread Group” menüsünden yeni bir thread group ekliyoruz. Thread group, testimizin entrypoint’i olarak görülebilir. Birden fazla thread group kullanılabilir, her thread group farklı bir test senaryosu olacaktır.

  • Action to be taken after a Sample error: Test boyunca bir hata ile karşılaşıldığında ne yapılacağını belirleriz. Hata oluşsa bile testimizin devam etmesini istediğimiz için “Continue” seçeneğini işaretledik.
  • Number of Threads (users): Toplam kaç thread (kullanıcı) ile testin yapılacağının bilgisi. Örneğimizde 600 olarak belirledik.
  • Ramp-up period (seconds): Thread’lerin toplam kaç saniyede oluşturulacağı. Örneğimizde 60 saniye olarak belirledik. Böylece testimizde saniyede 10 thread oluşturulacak dolayısıyla 10 istek gönderilecek.
  • Loop Count: Testin kaç kere tekrar edileceği. Örneğimizde bir tekrar yapacağımız için 1 olarak belirledik. Eğer 2 olarak belirleseydik ilk test bittikten sonra aynı parametre ve konfigürasyonlarla bir test daha başlatılacaktı.

Thread Group’a sağ tıklayarak “Add” -> “Config Element” -> “CSV Data Set Config” menüsünden yeni bir veri kaynağı ekliyoruz. Bu config element sayesinde her istek için farklı değerler gönderebiliyoruz. Böylece her seferinde aynı kaydı güncellemek yerine her seferinde farklı kayıt güncelliyoruz ve dinamik bir test oluşturuyoruz.

  • Filename: Veri kaynağı olarak kullanılacak dosya yolu.
  • File encoding: Dosya encoding türü.
  • Variable Names (comma-delimited): Değerlerin testimizde kullanacağımız değişken isimleri. Test senaryomuzun herhangi bir yerinde {ID} olarak o thread için ayrılmış satırda yer alan ID değerine ulaşabiliriz.
  • Ignore first line: Eğer eklediğimiz veri kaynağının ilk satırında verimiz varsa False yapılmalı, böylece ilk satırda yer alan veriyi kullanabiliriz. İlk satırda test ile alakası olmayan veriler (kolon ismi, test ile bilgiler gibi) varsa True seçilmeli, böylece ilk satır testimize dahil edilmeyecek.
  • Delimiter: CSV dosyasında yer alan veri ayracı. Bu örneğimiz için hazırladığımız dosyamızın ayracı “,” olarak belirlendi.

Buna göre ilk satır için ID değeri “26E6008168B6410792C863BCD67D95FC” ve VALUE değeri “benchmark_update_00001” olarak belirlenecek.

Diğer değerler default olarak bırakıyoruz.

Thread Group’a sağ tıklayarak “Add” -> “Config Element” -> “HTTP Request Defaults” menüsünden HTTP Request Defaults bileşeni ekliyoruz. Bu bileşen sayesinde testimizde oluşturulacak her thread için aynı olacak bilgileri belirliyoruz.

  • Protocol: Testimizde kullandığımız API http protokolünde çalıştığı için “http” değerini veriyoruz.
  • Server Name or IP: API “foframeworktemplateapinet6.ford.com.tr” sunucusunda çalıştığı için “foframeworktemplateapinet6.ford.com.tr” değerini veriyoruz.
  • Parameters: Göndereceğimiz isteğe parametre ekleyebiliyoruz.
  • Body Data: Göndereceğimiz isteğe body data ekleyebiliyoruz.

Thread Group’a sağ tıklayarak “Add” -> “Sampler” -> “HTTP Request” menüsünden HTTP Request bileşeni ekliyoruz. Bu bileşen sayesinde gönderilen her isteği yapılandırabiliyoruz. Testimiz için yeterli olan Basic tanımları belirliyoruz.

  • Protocol: Testimizde kullandığımız API http protokolünde çalıştığı için “http” değerini veriyoruz.
  • Server Name or IP: HTTP Request Defaults bileşeninde bu değeri belirttiğimiz için tekrar eklemiyoruz.
  • HTTP Request: Servisimiz POST metodunu kabul ettiği için “POST” seçiyoruz.
  • Path: Testi yapacağımız endpoint bilgisini giriyoruz.
  • Body Data: Post edeceğimiz değerleri json formatında giriyoruz. Değerlerimizi dinamik olarak CSV dosyamızdan alacağımız için CSV Data Set Config bileşeninde belirttiğimiz değişken isimlerini değer olarak ${…} formatında json değişkenlerimize atıyoruz. JMeter bizim için thread’a ait satırda yer alan değerleri kullanıyor.

HTTP Request’e sağ tıklayarak “Add” -> “Config Element” -> “HTTP Header Manager” menüsünden HTTP Header Manager ekliyoruz. Bu bileşen ile senaryomuzu gerçekleştirebilmek için gerekli olan “Connection”, “Accept” ve “Content-Type” bilgilerini ekliyoruz.

Thread Group’a sağ tıklayarak “Add” -> “Listener” -> “View Result Tree” menüsünden View Result Tree ekliyoruz. Bileşen sayesinde her test için JMeter’a dönen response’u görüntüleyebiliyoruz.

Thread Group’a sağ tıklayarak “Add” -> “Listener” -> “Summary Report” menüsünden Summary Report ekliyoruz. Bileşen sayesinde testin sonucunu toplu olarak görebiliyoruz.

Test ekranının yukarısında yer alan yeşil play butonuna basarak testi başlatıyoruz.

Test Sonuçları

Sonuçları eklediğimiz iki listener bileşeni ile test sonuçlarımızı görüntüleyebiliriz.

View Results Tree

1 ile işaretlenmiş alanda yer alan X/Y (0/600) değerleri anlık bekleyen istek sayısı (X) ve toplam istek sayısı (Y) değerlerini ifade etmektedir. Test süresince X değeri gözlemlenerek en yüksek bekleyen işlem sayısı gözlemlenebilir.

2 ile işaretlenmiş alanda testin toplam süresi gösterilmektedir. Testimizi 63 saniyede sürmüştür.

3 ile işaretlenmiş alan aracılığı ile sonuçlar dış bir kaynağa yazılabilir. “Browse” ile sonuçların kaydedileceği dosya seçilmeli.

4 ile işaretlenmiş alanda tüm testlerin sonuçları gösterilmektedir. Toplam 600 tane isteğin detaylarına bu alandan erişilebilir. Yeşil ikon ile gösterilmiş istekler olumlu, kırmızı ikon ile gösterilmiş istekler olumsuz sonuçlanmıştır.

5 ile işaretlenmiş alanda isteklere ait detay bilgiler gösterilmekte.

  • Sampler result: İstekle ilgili response code, content type gibi bilgiler yer alır.
  • Request: Gönderilen isteğe ait request bilgisi yer alır.
  • Response data: Gönderilen istek karşılığında sunucu tarafından dönülen response bilgisi yer alır.

Summary Report

View Results Tree’ye benzer şekilde sonuçlar dosya yolu belirtilerek dış kaynağa kaydedilebilir. Testi yorumlama açısından tabloda yer alan değerler oldukça önemlidir.

  • Label: Test senaryo adı.
  • #Samples: Aynı senaryo için gerçekleştirilen örnek sayısı.
  • Average: Test sonuçlarının ortalama tamamlanma süresi.
  • Min: En kısa sürede biten tekil testin tamamlanma süresi.
  • Max: En uzun sürede biten tekil testin tamamlanma süresi.
  • Std. Dev.: Senaryo tamamlanma sürelerinin standart sapması.
  • Error%: Hata ile sonuçlanan testlerin yüzdesi.
  • Throughput: Saniyede gerçekleştirilen test sayısı.
  • Received KB/sec: Alınan veri miktarı.
  • Sent KB/sec: Gönderilen veri miktarı.
  • Avg. Bytes: Senaryo testlerinin ortalama veri miktarı.

Testin yapılma amacına göre değerler incelenmelidir.

Uygulamalarımızın end point performans testlerini yapmak için oldukça kullanışlı bir tool olan JMeter’ın her geliştiricinin alet çantasında bulunması gerekmekte. Ücretsiz olması, kurulum maliyeti gerektirmemesi ve kullanım kolaylığı ile öne çıkan JMeter geliştirmeleri daha ölçülebilir hale getirme noktasında hepimizin ihtiyaç duyduğu desteği sağlamakta.

--

--