[PYTHON] So führen Sie einen Komponententest durch Teil 1 Entwurfsmuster zur Einführung

Klicken Sie hier für Teil 2

Um den Komponententest durchzuführen, müssen umgebungsabhängige Elemente wie Geräte ersetzt / entfernt werden. Wenn diese Handhabungen nicht sorgfältig entworfen wurden, sind keine Unit-Tests möglich. In einer Reihe von Artikeln in diesem Titel werden Implementierungen zum Testen und Produzieren unter Verwendung von Entwurfsmustern betrachtet. In diesem Artikel werden wir uns mit dem Umgang mit im Speicher gespeicherten Daten befassen. Gleiches gilt jedoch für Geräte wie Netzwerke.

Letztendlich liegt der Fokus darauf, wie das Testmodul ausgetauscht werden kann. Diese Idee heißt Dependency Injection (DI). In DI wird der Kopplungsgrad zwischen Modulen über die Schnittstelle reduziert.

Das Beispielprogramm ist in C ++ geschrieben, aber auch C # und Python werden geschrieben.

Geschichte verändern

26.04.2015 Python-Beispielcode hinzugefügt

Umgebungsabhängige Daten

Die Daten können alles sein, was das Verhalten der Anwendung bestimmt oder das Ergebnis des Verhaltens vermittelt. Sie können es lokal tun, aber es gibt Zeiten, in denen Sie es wirklich global verwenden möchten. Wie soll es aufbewahrt werden?

Im folgenden Beispiel wird eine Funktion angenommen, die ihr Verhalten abhängig von der Version des externen Moduls ändert.

//Vor der Einführung (nicht testbar oder schwierig)
void func() {
    //Version herunterladen
    int version = SomeModule::getMajorVersion();
    if (version > 10) {
        //Etwas mit der angegebenen Version zu tun
    }
}

Hier wird angenommen, dass "SomeModule :: getMajorVersion ()" nur in einer bestimmten Umgebung verwendet werden kann oder es schwierig ist, den Status zu wechseln. Mit einem solchen Code ist es schwierig, die folgende if-Anweisung zu testen.

Verwendung des Proxy-Musters

Erstellen Sie hier eine Dummy-Klasse, die "SomeModule" ersetzt, bereiten Sie eine Entität und einen Proxy vor, die auf den Dummy zugreifen, und machen Sie ihn testbar. Zunächst aus der Schnittstelle der Proxy-Klasse, die das Fenster ist.

class ModuleProxy {
	virtual int getMajorVersion_() const = 0;
protected:
	ModuleProxy() {}
public:
	virtual ~ModuleProxy() {};
	int getMajorVersion() const {
		return this->getMajorVersion_();
	}
};

Als nächstes kommt die reale Klasse und die Dummy-Klasse. Hier wird auch das ursprüngliche SomeModule ausgeblendet und die Verwendungsklasse erstellt.

//Klasse, die das externe Modul tatsächlich aufruft
class SomeModuleImpl : public ModuleProxy {
	virtual int getMajorVersion_() const override {
		return SomeModule::getMajorVersion();
	}
};

//Dummy-Klasse zum Testen
class ModuleDummy : public ModuleProxy {
	virtual int getMajorVersion_() const override {
		return major_;
	}
public:
	ModuleDummy(int ver = 0)
		: major_(ver)
	{}
	int major_;
};

Die Funktionsfunktion und der Testcode lauten wie folgt.

void func(ModuleProxy& module) {
    //Version herunterladen
    int version = module.getMajorVersion();
    if (version > 10) {
    }
}

void XXXTest::funcTest() {
   	ModuleDummy dummy(10);
    {
        func(dummy);
    }
    {
    	dummy.major_ = 11;
        func(dummy);
    }
}

Verwendung des Monostate-Musters

Eine andere Möglichkeit, dies zu implementieren, ist die Verwendung des Monostate-Musters. Hier ist die Elementfunktion ebenfalls statisch, kann jedoch eine normale Funktion sein.

class Data {
    static int majorVersion;
public:
    static int getMajorVersion() const {
        return majorVersion;
    }

    friend class XXXTest;
};
int Data::majorVersion = 1;

Die Anwendungsimplementierung, die dies verwendet, ist wie folgt.

void func() {
    if (Data::getMajorVersion() > 10) {
    }
}

Die Testseite sieht so aus.

void XXXTest::funcTest() {
    {
        Data::majorVersion = 10;
        func();
    }
    {
        Data::majorVersion = 11;
        func();
    }
}

Das Monostate-Muster ist einfach, aber Sie müssen über die Wertinitialisierung nachdenken. Wenn von anderen statischen Elementen verwiesen wird, muss in der Reihenfolge der Initialisierung vorsichtig vorgegangen werden.

Beispielcode (Python)

Die Python-Version des Monostate-Musters ist unten dargestellt. Für die Methode wurde eine Klassenmethode angegeben.

class Data:
    _majorVersion = 1

    @classmethod
    def getMajorVersion(cls) -> int:
        return cls._majorVersion

Die Testseite sieht folgendermaßen aus:

import unittest

class Test_testSample(unittest.TestCase):
    def test_version(self):
        Monostate.Data._majorVersion = 10
        self.assertFalse(Target.func())
        Monostate.Data._majorVersion = 11
        self.assertTrue(Target.func())

Zusammenfassung

In diesem Artikel wurde DI mithilfe des Proxy-Musters realisiert. Wir haben auch gezeigt, wie man das Monostate-Muster einfacher verwendet.

Neta ab dem nächsten Mal

Es ist wichtig, Verträge zu kennen, auch in Sprachen wie C ++ / C # / Python, die keine Vertragsfunktionalität unterstützen.

Da Monostate polymorph verwendet werden kann, ist es möglich, Proxy-Muster zu integrieren, um die Verwendung zu vereinfachen.

Es ist gut, friend im Komponententest zu verwenden, aber es fügt dem Header auf der Anwendungsseite einen Freund hinzu, was zu einer Neukompilierung führt. Überlegen Sie, wie Sie damit umgehen sollen.

Wenn Sie den Ressourcenzugriff mit shared_ptr implementieren, ist es möglicherweise besser, schwaches_ptr als IF des Proxys zu verwenden. Probieren Sie diese Verbesserungen aus, während Sie noch testbar sind.

Recommended Posts

So führen Sie einen Komponententest durch Teil 1 Entwurfsmuster zur Einführung
So führen Sie einen Komponententest durch Teil 2 Klassendesign zum Testen
Spigot (Papier) Einführung in die Erstellung eines Plug-Ins für 2020 # 01 (Umgebungskonstruktion)
Wie man ein Schießspiel mit toio macht (Teil 1)
So erstellen Sie ein Hacking-Labor - Kali Linux (2020.1) VirtualBox 64-Bit Teil 2-
So schreiben Sie einen Test für die Verarbeitung mit BigQuery
Wie erstelle ich eine japanisch-englische Übersetzung?
Wie man einen lockeren Bot macht
Wie erstelle ich einen Crawler?
So erstellen Sie eine rekursive Funktion
[Blender] So erstellen Sie ein Blender-Plug-In
Wie erstelle ich einen Crawler?
[Einführung in Python] Wie verwende ich den Operator in in der for-Anweisung?
[Python] Wie man eine Klasse iterierbar macht
[Cocos2d-x] So erstellen Sie eine Skriptbindung (Teil 2)
So erstellen Sie einen benutzerdefinierten Backtrader-Indikator
So testen Sie auf einer von Django authentifizierten Seite
Wie erstelle ich eine Pelican Site Map?
Erstellen Sie ein Schachbrettmuster für die Kamerakalibrierung
[Cocos2d-x] So erstellen Sie eine Skriptbindung (Teil 1)
So erstellen Sie mit YOLO in 3 Stunden ein Modell für die Objekterkennung
Wie man ein Dialogsystem für Anfänger erstellt
So erstellen Sie ein Wörterbuch mit einer hierarchischen Struktur.
So erstellen Sie ein QGIS-Plug-In (Paketerzeugung)
So schreiben Sie einen ShellScript Bash für Anweisung
Ich las "Wie man ein Hacking Lab macht"
So erstellen Sie das Substance Painter Python-Plugin (Einführung)
Wie man Python für Anfänger schneller macht [numpy]
[Einführung in Python] So erhalten Sie den Datenindex mit der for-Anweisung
Tipps für Python-Anfänger, um das Scikit-Image-Beispiel für sich selbst zu verwenden 7 Erstellen eines Moduls
[Go] So erstellen Sie einen benutzerdefinierten Fehler für Sentry
[Einführung in Python] Hochgeschwindigkeits-Einführung in Python für vielbeschäftigte C ++ - Programmierer
So testen Sie eine Funktion, die die aktuelle Zeit enthält, mit Freezegun in Python
So erstellen Sie ein Python-Paket mit VS Code
Einführung in PyQt4 Teil 1
So erstellen Sie ein lokales Repository für Linux
So erstellen Sie eine Entwicklungsumgebung für TensorFlow (1.0.0) (Mac)
Grundlagen von PyTorch (2) - Wie erstelle ich ein neuronales Netzwerk?
Schreiben Sie Code in UnitTest, eine Python-Webanwendung
[Einführung in Python] So schreiben Sie sich wiederholende Anweisungen mit for-Anweisungen
So erstellen Sie mit Flask einen BOT für Cisco Webex-Teams
[Python] So erstellen Sie eine Liste von Zeichenfolgen Zeichen für Zeichen
So mischen Sie einen Teil der Python-Liste (at random.shuffle)
Wie erstelle ich ein Multiplayer-Online-Actionspiel mit Slack?
Experimentieren Sie mit Python, um ein PDF für Selbstversorger für Kindle zu erstellen
So definieren Sie mehrere Variablen in einer Python for-Anweisung
So erstellen Sie ein Hacking-Labor - Kali Linux (2020.1) VirtualBox 64-Bit-Edition -
Wie man ein einfaches Flappy Bird-Spiel mit Pygame macht
So ersetzen Sie eine Teilübereinstimmung durch einen numerischen Wert (Anmerkung 1)
[Einführung in Tensorflow] Verstehen Sie Tensorflow richtig und versuchen Sie, ein Modell zu erstellen
Erstellen Sie ein Blueqat-Backend ~ Teil 1
Erstellen Sie ein Blueqat-Backend ~ Teil 2
Ich habe einen Unit-Test für verschiedene Sprachen geschrieben
Geben Sie die Pytest-Clean-Parameter für den Test der Kolbeneinheit an
Python-Unit-Test
So führen Sie einen Komponententest durch Teil 2 Klassendesign zum Testen
Eine super Einführung in Linux
So rufen Sie eine Funktion auf
Wie man ein Terminal hackt