C/C++ Yazılım Testi Hk.

Başlatan quarko, 17 Mayıs 2023, 08:51:33

quarko

Arkadaşlar merhaba,

Gömülü sistemler tarafında C/C++ dilleriyle yazılım geliştirip test süreçleri hakkında bilgi sahibi olan var mıdır ? Nasıl ilerlenilmeli ? Code Coverage, Static Analysis, Unit Test, Integration Test gibi konulara nasıl hakimiyet sağlanabilir ? Bu konuda Parasoft, Vector Cast, Cantata gibi araçlar kullanan var mıdır ?

Bu konulardaki tecrübelerimizi paylaşmanın istifadeli olacağını düşünüyorum.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

Tagli

Bu benim de çok merak ettiğim bir konu. Donanım tarafı ağır basan bir projede, mesela bir motor sürücüde, yazılım testlerinin otomatik olarak nasıl yapılabileceğini bir türlü hayal edemedim. Belki örneğin motoru ve enkoderi yazılımsal olarak simüle edip sürücüyü kandırarak test yapmak mümkün olabilir, ancak bazı donanımların modellenmesi ve taklit edilmesi başlı başına bir proje. Hem onların (taklitlerin) doğru çalıştıklarından nasıl emin olacağız? Mantıken onların da test edilmeleri gerekecek.
Gökçe Tağlıoğlu

quarko

Yazılımla donanımı birlikte test edebilmek HIL sistemleri mevcut hocam. O şekilde geliştirilen yazılımın fonksiyonelliği en iyi şekilde test edilebilir. Ama sadece yazılım testi denince, aslında fonksiyonellikten ziyade daha hatasız çalışan, daha optimize ve güvenli kod geliştirme diye anlıyorum ben. Örneği statik analiz olayında, yazılımdaki her bir modül, çeşitli standartlar çerçevesinde değerlendiriliyor. En hatasız, en güvenli şekilde kod ortaya çıkarılmaya çalışıyor, anladığım kadarıyla. Coverage analizlerinde kodun % kaçı kullanıldığına dair analiz yapılıyor ve belirli oranlar ediliyor. Bu oranlarında belirli seviyelerde olması bekleniyor. Unit test ve integration test konuları apayrı zaten.

Bende henüz bu test olayını tam idrak etmiş değilim. Anlamaya çalışıyorum ama kendine has bir jargonu, kültürü, yapısı, ekosistemi var. Bu işleri tecrübe edenler de çok az. Gömülü sistem tarafında çok daha az. Havacılıkta DO178-B/C süreçlerine uygun şekilde ürün geliştirebilmek için bu konular aslında çok önem arz ediyor.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

Mr.Thinking

#3
Bu test olayı, yazdığınız kodun uygulama sırasında uçağın düşmesine sebep olabilecek bir hataya neden olabileceği ile ilgilimi.
Biraz inceledim de bu iş Elektroniğin Tanrısı gibi duruyor.
ego=1/Knowledge

quarko

Konumuz her ne kadar yazılım testi kapsamında olsa da, havacılıkta yapılan donanım ve yazılım tasarımlarının güvence düzeyleri var. Donanım tarafında DO-254, yazılım tarafında DO-178/C süreçleri üzerinden bir DAL (Design Assurance Level - Tasarım Güvence Düzeyi) seviyesi atanır.

https://thecloudstrap.com/design-assurance-level-dal-in-do-178c/
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

Mr.Thinking

#5
Alıntı yapılan: quarko - 17 Mayıs 2023, 13:45:52Konumuz her ne kadar yazılım testi kapsamında olsa da, havacılıkta yapılan donanım ve yazılım tasarımlarının güvence düzeyleri var. Donanım tarafında DO-254, yazılım tarafında DO-178/C süreçleri üzerinden bir DAL (Design Assurance Level - Tasarım Güvence Düzeyi) seviyesi atanır.

https://thecloudstrap.com/design-assurance-level-dal-in-do-178c/
Uçak eğitim simülatörlerine, devre donanımını çalıştırabileceğimiz mekatronik, ek bir şeyler yapılsa bu test gerçekleştirilemez mi. Örneğin flapleri veya iniş takımlarını açan devre gibi. Yazılımın kritiklik düzeyi illa sanal ortamda mı simüle veya test edilmesi gerekiyor. Çok basitemi indirgemiş oldum. Anlamaya çalıştığımdan soruyorum sadece.
ego=1/Knowledge

apsis

DO178 gibi süreçler çok detaylı raporlama ve dünyada havacılık/askeri taraftan kabul görmüş lisanslı tool'lar ister. Bu tool'lar çok ciddi paralar.
Code coverage en temel statik kod yöntemi. Hatta ilk bununla başlanır diyebilirim. Sonrası dinamik testler ve çok yıpratıc bir raporlama süreci.
Bu 1 2 kişiyle yürütülecek bir aşama değil.ya

Bunun haricinde yazılım test için unit test sıklıkla kullanılır. Bunun için öncelikle design pattern'lerini araştırmanızı tavsiye ederim.
"Makineye Beyin" MEKATRONİK

Sozuak

Mission critical dediğimiz cihazlarda  çift devre paralel çalışır 3. devre sonuçları karşılaştırır. Tek sisteme bağlı kalmaz. Kalp atışı dediğimiz bir sistemle de  sistem tick kontrol edilir kilitlenme varsa reset atılır. Kritikse son durum sürekli kaydedilir başlayınca o parametreler geri yüklenir vs vs.  Ate dediğimiz sistemlerde devre yada modül bir bütünün içinde çalışıyormuş gibi koşturulur. İstediğiniz hızda istediğiniz patterni uygulayıp (buna seri paralel çok kanaldan veri katarları da dahil)  sonuçlar olması gerektiği gibi mi karşılaştırılır. Donanım testlerinde de 2 bacaklı elemanlar açık devre ve kısa devre yapılarak normal işletim esnasındaki sonuçlara hem elektriksel hem de gerekirse mantıksal olarak bakılır. Çok bacaklı elemanlarda ise tabi o bacağın elektriksel konumuna ve kapasitesine  bağlı açıkdevre,  ground kısadevreleri yapılarak sonuçlara bakılır. Çıkış paternine göre  noktasal hata yada genel hata olarak çoklu elemanlar olasılık olarak verilir. Bazı kart yada modüllerde sadece var olan konnektörlere bağlantı yapılırken bazılarında da ek olarak pin to pin  ek bağlantılar da yapılır.

quarko

Alıntı yapılan: apsis - 17 Mayıs 2023, 19:29:20DO178 gibi süreçler çok detaylı raporlama ve dünyada havacılık/askeri taraftan kabul görmüş lisanslı tool'lar ister. Bu tool'lar çok ciddi paralar.
Code coverage en temel statik kod yöntemi. Hatta ilk bununla başlanır diyebilirim. Sonrası dinamik testler ve çok yıpratıc bir raporlama süreci.
Bu 1 2 kişiyle yürütülecek bir aşama değil.ya

Bunun haricinde yazılım test için unit test sıklıkla kullanılır. Bunun için öncelikle design pattern'lerini araştırmanızı tavsiye ederim.

Evet hocam bu süreçler birkaç kişi ile yürütülecek işler değil. Bu aslında bir iş yapma kültürü. Biz millet olarak, yeni bir işe başlarken sahip olduğumuz heyecanla hızla kolları sıvarız. Sonrasında farklı şartlar nedeniyle işi ya bırakırız, ya da istediğimizi tam olarak elde edemeden olayı kapatırız.

Bu yapı ise, işi yapmadan önce nasıl yapacağımızı tüm detaylarıyla planlayıp, dokümante edip ondan sonra işe koyulmayı hedefliyor. Büyük tecrübe gerektiriyor. Her iki yönteminde kendine göre avantajları ve dezavantajları mevcut.

-----------

Ayrıca bu yazılım testi konularındaki detaylara hakimiyet sağlamak adına tavsiye edebileceğiniz kitap varsa, beklerim.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

quarko

"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

kantirici

#10
Merhaba,

Konuya embedded taraftan bakacak olursak ilk olarak testlerin hedef donanım üzerinde mi yoksa geliştirme ortamında mı çalıştırılacağına karar veriliyor. Eğer hedef donanım üzerinde testlerin çalıştırılması bir ihtiyaç yada hedef ise yukarıdaki bahsedilen HIL sistemlerine konu genişliyor.

Ama çoğu durumda testler geliştirme yapılan ve çoğunlukla PC'ler üzerinde çalıştırılıyor.Bu konuda detaylı ama ilk etapta önemli değil.

Gömülü sistemlerde yazılım testlerinde ana hedef iş yapan kod parçalarının (business logic) uç durumlar (edge case) ki davranışları ve kod bloğunun beklenen davranışı sergileyip sergilemediğinin henüz geliştirme aşamasında tespit edilmesi ve çözülmesi diyebiliriz. Bu iş içinde birim testler (unit test) ler yazılıyor. TDD, test driven developmont da burada başlıyor aslında.

İş yapan yazılım birimleri eğer doğrudan donanıma erişiyor ise burada iki farklı yol izleniyor. Ya bu donanımı sanal bir yazılım ile değiştirmek (mocking) yada bağımlılıkları mümkün mertebe kırarak, middleware gibi katmanlı yazılım geliştirerek en alt kısmın donanıma çıkmasını sağlamak ve o kısmı hiç test etmemek. Çünkü register seviyesinde işlerin beklenen gibi gideceği yada üretici tarafından sağlanan 3rd yazılımların doğru çalıştığı kabul edilir.
Burada ikinci yol en çok tercih edileni çünkü mock'lamanında dezavantajları var.

Küçük bir örnek ile konuyu pekiştirelim.

Örneğin ADC'ye bağlı bir sıcaklık sensörümüz olsun. Sensörün ürettiği değer sıcaklık ile değişiyor ve gerilim seviyesinden sıcaklığa geçiş içinde bir fonksiyon vermiş olsun. Bu durumda aşağıdakki gibi bir yapı olacak.
 
/*adc.h -->Donanıma erişen yazılım modülü*/
uint16_t adc_read(uint8_t channel);

/*temperature.c*/
#include "adc.h" -->Bağımlılık geldi.
#define ADC_CHNL 1

float ftemp = 0.0f;

float get_filtered_temp()
{
    return ftemp;
}

float get_temp(void)
{
    float temp = 0.0f;
    uint16_t temp_raw = adc_read(ADC_CHNL);

    temp = 25 + ((3.1415 * temp_raw) / 1.78);
    temp += magic_val; //datashetten geldi

    ftemp = (temp + ftemp) / 2;

    return temp;
}

/*test_temperature.c*/
#include "temperature.h"
#include "mock_adc.h"

void setUp(void)
{
}

void tearDown(void)
{
}

void test_when_adc_raw_min_then_temp_should_zero(void)
{
    adc_read_ExpectAndReturn(0x01F1); 0x1F1, min. sensor degeri, datashetten
    float temp = get_temp();
    TEST_ASSERT_EQUAL_FLOAT(0, temp);
}

void test_when_adc_raw_max_then_temp_should_127_Deg(void)
{
    adc_read_ExpectAndReturn(0x01F1); 0x20F, max. sensor degeri, datashetten
    float temp = get_temp();
    TEST_ASSERT_EQUAL_FLOAT(127.5, temp);
}
void test_when_adc_1FF_then_temp_should_73_Deg(void)
{
    adc_read_ExpectAndReturn(0x01FF); 0x20F, max. sensor degeri, datashetten
    float temp = get_temp();
    TEST_ASSERT_EQUAL_FLOAT(73, temp);
}
void test_filtered_temp()
{
    TEST_ASSERT_EQUAL_FLOAT((127.5 / 2), get_filtered_temp());
}

Yukarıda adc modulü içinde adc'den okuma yapan adc_read isimli fonksiyon var. Bu doğrudan donanıma register seviyesinde erişiyor. Fakat biz testler PC'de çalıştıracağımız için test'lerde bunu mockladık. Bu mock'lama işi otomatik oluyor, yani bizim bir şey yazmamıza gerek yok. Bu işlemde header dosyasında ki tanımlamalara göre yapılıyor.

temperature modülünde iki fonksiyon var. Bir tanesi adc den ham datayı okuyup datasheetteki yönergelere göre işlemleri yapıyor. Diğeri ise ortamala sıcaklığı veren bir fonksiyon.

Şimdi testlerde esas olan alt sınır üst sınır ve bir ara değere göre bu ham ADC değerinden gerçektekten beklenen sıcaklıklar hesaplanabilyor mu onların testini yazdık.

Testleri yazarken mocklanan modüller için, hangi fonskiyonun hangi fonksiyonlara çağrı yapacağını bildiğimiz için ilk önce fonksiyonun çağrılmasını beklediğimizi ve geri dönüş değeri olarak ne döndürmesi gerektiğini belirttik. Sonra fonskiyona çağrı yapıp sıcaklık değerini okuduk ve gerçekten beklene değer mi diye bir assertion ile kontrol ettik. Eğer beklenen değer ile fonksiyondan dönen değer farklı olursa bu test hata verecek.

Yazılımın ne kadar donanıma bağımlı olduğu hiç önemli değil. Burada ana kriter geliştirlen yazılımın bağımlılığı az olması. Sonuçta birimler bazı hesaplamalar, kopyalama, taşıma vb işlemler yapıp çıktı üretecek. Bizde bu birmler gerçekten verilen girdiye beklenen çıktıyı üretiyor mu bunu test etmek.

Bu konu ile ilgili olarak gömülü sistemlerde çok popüler olan ceedling'i incelmenizi öneririm. Kendi içinde de çok detaylı örnek var. Konu çok detaylı, testler de çok çeşitli, birim, fonksiyonel, entegrasyon testleri vs... ama konuyu biraz anlayınca aslında basit bir olay olduğunu göreceksiniz.

Ayrıca gömülü sistemlerde de son zamanlarda sıklıkla kullanılmaya başlandığınıda belirteyim.