Pytanie Rozwój oparty na testach dla bibliotek przetwarzania sygnałów


Pracuję z manipulacją dźwiękową, zazwyczaj używając Matlaba do prototypowania i C ++ do implementacji. Ostatnio czytałem o TDD. Przejrzałem kilka podstawowych przykładów i jestem całkiem entuzjastycznie nastawiony do tego paradygmatu.

W tej chwili używam tego, co uważam za globalne podejście "testowane". W tym celu piszę bloki przetwarzania sygnałów w C ++, a następnie tworzę prosty plik mex Matlab, który może łączyć się z moimi klasami. Następnie dodam funkcjonalność, sprawdzając, czy wyniki pasują do odpowiadającego jej skryptu Matlaba. To działa dobrze, ale testy stają się przestarzałe szybko, gdy system ewoluuje. Furtermore, testuję cały system, a nie tylko jednostki.

Byłoby miło użyć ustalonego środowiska TDD, w którym mogę mieć pakiet testowy, ale nie widzę sposobu, w jaki mogę zweryfikować funkcjonalność bloków przetwarzania bez testów, które są równie złożone jak testowany kod. W jaki sposób wygenerowałbym sygnały odniesienia w teście C ++, aby zweryfikować blok przetwarzania, bez testu będącego formą samospełniającego się proroctwa?

Jeśli ktokolwiek ma doświadczenie w tej dziedzinie lub może zasugerować kilka metod, które mogłem przeczytać, byłoby świetnie.


12
2018-05-29 09:13


pochodzenie


+1 przetwarzanie sygnału testowania nie jest łatwe; jedna uwaga: testowanie, że wyniki w języku C ++ są takie same, jak wyniki matlab, tylko dowodzi tego punktu, ale nie dowodzi, że wyniki są poprawne: zarówno matlab, jak i c ++ mogą dawać taki sam, niepoprawny wynik - stijn


Odpowiedzi:


Myślę, że wspaniale jest zastosować podejście TDD do przetwarzania sygnału (zaoszczędziłoby mi to miesięcy, gdybym wiedział o tym wiele lat temu, kiedy sam przetwarzałem sygnał). Myślę, że kluczem jest rozbicie systemu na komponenty najniższego poziomu, które mogą być niezależnie testowane, np .:

  • FFT: testuj sygnały przy znanych częstotliwościach: DC, Fs / Nfft, Fs / 2 i różnych fazach itp. Sprawdź, czy szczyty i faza są zgodne z oczekiwaniami, sprawdź, czy stała normalizacyjna jest taka, jak oczekujesz
  • zbieranie szczytów: sprawdź, czy poprawnie znalazłeś maksima / minima
  • Filtry: generuj dane wejściowe przy znanych częstotliwościach i sprawdź amplitudę wyjściową oraz fazę zgodnie z oczekiwaniami.

Jest mało prawdopodobne, aby uzyskać dokładnie takie same wyniki występują między C ++ i Matlab, więc będziesz musiał podać granice błędu w niektórych testach. TDD to świetny sposób nie tylko sprawdzenia poprawności kodu, który masz, ale jest bardzo przydatny podczas wypróbowywania różnych implementacji. Na przykład, jeśli chcesz zastąpić jedną implementację FFT inną, często występują niewielkie różnice w sposobie pakowania danych lub używanej stałej normalizacji. TDD da ci wysoki stopień pewności, że nowa biblioteka jest poprawnie zintegrowana.


3
2018-05-29 14:22





Robię coś podobnego do detekcji heurystycznej, a my mamy ładunki i ładunki plików przechwytywania i ramy, aby móc je załadować i wstrzyknąć do testów. Czy masz możliwość przechwycenia sygnałów referencyjnych w pliku i zrobić to samo?

Jeśli chodzi o moje 2 centy dotyczące TDD, to świetny sposób na rozwój, ale tak jak w przypadku większości paradygmatów, nie zawsze musisz podążać za tym do listu, są chwile, kiedy powinieneś wiedzieć, jak nieco zgiąć zasady, tak aby nie napisać zbyt dużo kodu / testów wyrzucenia. Czytałem o jednym podejściu, które mówi, że absolutnie żaden kod nie powinien być napisany, dopóki test nie zostanie opracowany, co czasami może być zbyt surowe.

Z drugiej strony, zawsze lubię mówić: "Jeśli nie jest przetestowany, jest zepsuty" :)


2
2018-05-29 09:22





Test może być tak złożony lub bardziej złożony, jak tworzony kod. Jeśli zmienisz (zaktualizujesz, naprawisz, naprawi błąd) kod, a nie test, test jednostkowy ostrzeże cię, że coś się zmieniło i trzeba go przejrzeć (czy błąd w trybie A miał zmienić tryb B ?, itd.)

Ponadto można zachować interfejsy API dla poszczególnych komponentów obliczeniowych, a nie tylko dla całego systemu end-to-end.


1
2018-05-29 15:16





Właśnie zacząłem myśleć o TDD w kontekście przetwarzania sygnału, więc mogę tylko dodać trochę do poprzednich odpowiedzi. To, co zrobiłem, polega na wykorzystaniu superpozycji do testowania prymitywów. Na przykład, testując filtr IIR, niezależnie zweryfikowałem elementy b0, b1 i b2 z jednostkowymi i skalowanymi wzmocnieniami, a następnie zweryfikowałem elementy a1 i a2, które następnie łatwo modelowały rozpady. Mój sygnał testowy był kombinacją funkcji ramp dla licznika i funkcji impulsu dla mianownika. Wiem, że to trywialny przykład, ale proces powinien zadziałać w przypadku wielu liniowych operacji. Testy powinny również wykonywać niestabilne regiony i pokazać, że wyjścia odpowiednio eksplodują.

Ogólnie rzecz biorąc, spodziewam się, że reakcje impulsowe wykonają dla mnie wiele pracy, ponieważ wiele sytuacji zmniejszy się do funkcji trygonometrycznych, które można niezależnie obliczyć. Podobnie, jeśli twoja operacja ma rozszerzenie serii, twoja funkcja testowa może przeprowadzić ekspansję do odpowiedniego zamówienia i porównać z twoim blokiem przetwarzania. Będzie wolno, ale powinno działać.


0
2017-08-17 08:29