Comment puis-je tester l'unité audio?

13

J'ai hérité d'un petit projet et je souhaite l'étendre et le stabiliser en même temps en écrivant des tests unitaires pour tout le nouveau code que j'ajoute. La première classe, TypedAudioCreatorcrée des fichiers audio, ce qui s'est avéré très facile à tester en premier et à écrire du code pour la seconde.

Cependant, quand est venu le temps d'écrire TypedAudioPlayer, je ne savais pas comment le tester. C'est une toute petite classe qui se concentre sur les bases du jeu du son:

public class TypedAudioFilePlayer
{
    public event StartedPlayingHandler StartedPlaying;
    public event StoppedPlayingHandler StoppedPlaying;

    public readonly int TimeBetweenPlays;

    private Queue<TypedAudioFile> _playlist = new Queue<TypedAudioFile>(); 

    public TypedAudioFilePlayer(int timeBetweenPlays)
    {
        TimeBetweenPlays = timeBetweenPlays;
    }

    public void AddFile(TypedAudioFile file)
    {
        _playlist.Enqueue(file);
    }

    public void StartPlaying()
    {
        ThreadPool.QueueUserWorkItem(ignoredState =>
        {
            while (_playlist.Count > 0)
            {
                var audioFile = _playlist.Dequeue();

                if (StartedPlaying != null)
                    StartedPlaying(audioFile);

                audioFile.SoundPlayer.PlaySync();
                audioFile.SoundPlayer.Dispose();

                if (StoppedPlaying != null)
                    StoppedPlaying(audioFile);
            }
        });
    }

    public void StopPlaying()
    {
        if (StoppedPlaying != null)
            StoppedPlaying(null);
    }
}

Je suis encore très nouveau chez TDD, mais je me rends compte des avantages de la pratique et j'aimerais essayer de m'améliorer. J'ai écrit Code en premier, pas de tests ici, mais c'était juste que j'étais trop paresseux pour penser correctement à la façon de résoudre le TDD. Ma question est la suivante: comment dois-je / pourrais-je tester cette classe?

IAE
la source
2
N'y a-t-il pas des frameworks moqueurs en C #? Cela devrait résoudre vos problèmes.
user43552
2
@ user43552: Ce serait juste tester une maquette ... ce scénario est destiné à tester le lecteur audio.
Steven Evers
5
Je ne sais pas comment faire de l'audio en C #, mais il me semble que vous devez refactoriser cette classe afin de pouvoir injecter une maquette à la place de audioFile.SoundPlayer. Ensuite, testez avec cette maquette et vérifiez que PlaySyncet Disposesont appelés aux bons endroits. Vous voulez également pouvoir injecter le StartedPlayingHandleret le StoppedPlayingHandlersi possible.
Dawood dit de réintégrer Monica le
2
Cela ne devrait-il pas être sur stackoverflow?
Amr H. Abd Elmajeed
3
@ AmrH.AbdelMajeed - pourquoi? Tout simplement parce qu'il a du code?
ChrisF

Réponses:

10

Il y a beaucoup de choses "sur les bords" de la plupart des systèmes qui ne peuvent pas être testés de manière adéquate. Par exemple, tout ce qui produit des graphiques ou du son. Pour ces types de systèmes, il vaut probablement mieux faire des tests manuels. Même avec une solution automatisée, ces sorties sont destinées à la perception humaine. La seule façon de savoir que vous produisez l'effet souhaité est de faire interagir un humain avec eux.

Il peut être possible d'effectuer un test manuel, puis d'enregistrer la sortie de ce test manuel et de créer un test automatisé garantissant que la sortie ne change pas. Soyez averti cependant que des tests comme ceux-ci sont incroyablement fragiles: toute modification du code sous-jacent peut nécessiter une répétition du test manuel, puis la création d'un nouvel enregistrement pour le test automatisé.

Chris Pitman
la source
1
+1 pour 'Il y a beaucoup de choses "sur les bords" de la plupart des systèmes qui ne peuvent pas être testés de manière adéquate. "
2
Cette réponse est très trompeuse. Tout simplement parce que le périphérique de sortie final pour le code audio est souvent une paire d'enceintes, cela ne signifie pas que le code audio ne peut pas être testé à l'unité ou qu'il doit être testé perceptuellement. Tous les logiciels audio ont une sortie numérique qui peut être mesurée et comparée à une sortie attendue. Une approche du test unitaire de l'audio peut être trouvée dans cet article
jb
9

Il est évidemment difficile de tester automatiquement que le lecteur audio lit vraiment l' audio, mais vous pouvez quand même créer des tests unitaires utiles. Par exemple, vous pouvez tester que StartPlaying () provoque l'événement StartedPlaying et StopPlaying () provoque l'événement StoppedPlaying. Vous pouvez tester le comportement lorsque vous essayez de lire une liste de lecture vide ou une liste de lecture nulle. Vous pouvez tester que AddFile ajoute vraiment le fichier à la liste de lecture. Vous pouvez tester qu'après avoir lu un fichier audio, il est supprimé de la liste de lecture (si vous le souhaitez). Il y a peut-être aussi des cas d'angle pour les fichiers audio cassés, etc. qui méritent d'être testés.

Ayant des tests unitaires pour ces choses, vous pouvez être sûr que la classe se comporte bien, c'est-à-dire qu'elle respecte ses contrats. Si c'est le cas, mais ne produit toujours aucun son, c'est relativement facile à détecter dans les tests manuels.

user281377
la source
3

Gardez à l'esprit qu'il existe une différence entre les tests unitaires , qui consiste à écrire de petits tests qui testent des unités individuelles de votre code, et des lanceurs de tests automatisés qui exécutent vos tests unitaires, généralement dans le cadre du processus de construction ou d'une sorte de processus continu. système d'intégration.

Les tests unitaires sont généralement automatisés, mais peuvent toujours être effectués manuellement. L'IEEE ne privilégie pas l'un par rapport à l'autre. L'objectif des tests unitaires est d'isoler une unité et de valider son exactitude. Une approche manuelle des tests unitaires peut utiliser un document pédagogique étape par étape.

( http://en.wikipedia.org/wiki/Unit_testing#Techniques )

Vous pouvez facilement écrire un test unitaire pour vérifier qu'un composant du lecteur audio lit correctement le son:

  1. Assurez-vous que vos haut-parleurs fonctionnent et que le volume est augmenté.
  2. Accédez au dossier / my / test /.
  3. Exécutez myTestRunner audioPlayerTest.script.thingee.
  4. Vous devriez entendre la 5e symphonie de Beethoven jouer pendant 15 secondes.
  5. Si vous n'avez rien entendu, que l'audio a joué plus ou moins de 15 secondes ou a été déformé de quelque façon que ce soit, le test a échoué. Sinon, le test a réussi.

Ce que vous ne pouvez pas faire facilement, c'est inclure ce test dans un système de test automatisé. Les tests automatisés sont une implémentation particulière des tests unitaires, mais ce n'est pas la seule implémentation.

Voir aussi: /programming/1877118/is-unit-testing-always-automated

lfaline
la source