Teilen Sie das zweite Kapitel über Probefahrten. Die Tests hier sind hauptsächlich für Web-Back-End-Tests gedacht – warum Sie Testfälle schreiben sollten (das heißt, ob die Verbesserung von Testfällen Zeitverschwendung ist), wie Sie Ihre Testfälle verbessern können, wie Code-Design das Schreiben von Testfällen vereinfachen kann und einige spätere Ideen.
1. Warum sollten Sie Testfälle schreiben?
Diese Angewohnheit wird normalerweise als Verhalten angesehen, das den Entwicklungsfortschritt verzögert. Sie müssen fast die gleiche Zeit damit verbringen, Ihren Code zu entwickeln, um Ihre Testfälle schrittweise zu verbessern. Wenn Sie jedoch während des Entwicklungsprozesses nach der Entwicklung eines Codeabschnitts dafür verantwortlich sind und das Problem nicht dem Tester überlassen, führen Sie zu diesem Zeitpunkt normalerweise einige manuelle Tests durch. Zum Beispiel:
Führen Sie bestimmte Methoden im Code aus, um zu sehen, ob der Ausgabewert wie erwartet ist.
Ändern Sie die Datenbank/den Cache und führen Sie dann bestimmte Methoden aus, um zu sehen, ob die Datenbankänderungen wie erwartet sind.
Verwenden Sie Tools, um die Anforderung bestimmter Schnittstellen zu simulieren, um zu sehen, ob der Rückgabewert der Schnittstelle/der geänderte Wert in der Datenbank den Erwartungen entspricht.
Wenn eine Front-End-Seite vorhanden ist, umfasst dies auch das gemeinsame Debuggen von Front-End und Back-End, d die Richtigkeit des Back-End-Codes.
Moderne Testtools versuchen ihr Bestes, dieses manuelle Testverhalten in Codeblöcke zu abstrahieren. Wenn Sie bewusst manuelle Tests durchführen, haben Sie tatsächlich damit begonnen, das Verhalten des Testfalls auszuprobieren. Da Tests manuell durchgeführt werden können, warum müssen Sie dann Code verwenden, um Tests zu implementieren?
Der Code kann wiederverwendet werden oder durch einfaches Refactoring mehr Funktionen erreichen. Wenn Sie sich jedoch dafür entscheiden, dies manuell zu tun, müssen Sie jedes Mal von vorne beginnen.
Ein ausgereifter Workflow sollte einen Codeüberprüfungsprozess umfassen. Es gibt viele Möglichkeiten, Ihren Code Satz für Satz zu überprüfen oder die Vollständigkeit und Richtigkeit Ihres Testcodes zu überprüfen und dann Ihre Testfälle auszuführen. Letzteres ist einfacher.
Wenn Code geändert wird, beispielsweise um einen Fehler zu beheben, ist es schwierig zu garantieren, dass sich Ihre Änderungen auf andere Teile auswirken, die von Ihrem Code abhängen. Im Zeitalter manueller Tests gibt es sogenannte Regressionstests, bei denen Ihr System erneut getestet wird, nachdem Sie den Fehler behoben haben. Wenn Sie jedoch bereits über einen vollständigen Testfall verfügen, führen Sie den Befehl einfach direkt aus.
Wenn Sie Ihren Code umgestalten, gilt das Gleiche.
2. So verbessern Sie Ihre Testfälle
Bevor Sie in die Verfeinerungsphase eintreten, besprechen Sie zunächst, wie Sie den Testfall implementieren werden.
describe Meme do before do @meme = Meme.new end describe "when asked about cheeseburgers" do it "must respond positively" do @meme.i_can_has_cheezburger?.must_equal "OHAI!" end end describe "when asked about blending possibilities" do it "won't say no" do @meme.will_it_blend?.wont_match /^no/i end end end
Der obige Code stammt aus Rubys Minitest. Der darin enthaltene Codeblock muss vor der Ausführung des folgenden Testfalls ausgeführt werden. Er unterstützt normalerweise auch eine entsprechende Methode, die nach der Ausführung des Testfalls ausgeführt werden soll. In jedem Anwendungsfall werden einige kleine Urteile gefällt.
Im ersten Absatz wurden einige Testinhalte erwähnt, die häufig bei manuellen Tests eine Rolle spielen. Hier sind 2 und 3 davon zur Erläuterung. Wenn Sie datenbankbezogene Tests durchführen, müssen Sie vorher einen Teil der Testdaten einfügen und die Testdaten danach löschen. Im mittleren Testfall wird die Korrektheit des Codes durch Ausführen der entsprechenden Methode bestätigt. Nach Abschluss der Ausführung: Überprüfen Sie die Datenänderungen/prüfen Sie, ob erwartete Ausnahmen vorliegen/ob die erwarteten Ergebnisse zurückgegeben werden. Wenn es sich um eine Schnittstelle handelt, wird die entsprechende Anforderung über den Code initiiert und anschließend überprüft, ob der zurückgegebene Inhalt die erwarteten Ergebnisse zurückgibt. Überprüfen Sie ggf., ob die Daten in der Datenbank den erwarteten Änderungen entsprechen.
Sie haben jetzt einen Testfall, aber es gibt noch einen Sonderfall, der berücksichtigt werden muss. Ich habe jetzt einen relativ vollständigen Testfall für eine Funktion geschrieben. Nachdem ich ihn ausgeführt habe, habe ich den Test bestanden, aber festgestellt, dass in den Online-Protokollen immer noch Fehler für diese Funktion vorhanden sind. Nach der Überprüfung stellte ich fest, dass ein bestimmter Zweig der Funktion zuvor nicht getestet wurde. Es kam vor, dass etwas in diesem Zweig ausgeführt wurde. Infolgedessen wurde ein sehr unklarer Syntaxfehler gemeldet dass alle Codes korrekt sind? Was hier eingeführt werden muss, ist ein Konzept namens Testfallabdeckung. Grundsätzlich verfügt jede Sprache über eine entsprechende Implementierung. Durch die Testfallabdeckung können wir Ihnen quantitativ sagen, ob Ihr Testfall den gesamten Code in einer bestimmten Datei durchlaufen hat. Sie müssen sicherstellen, dass Ihre Abdeckung so weit wie möglich bei 100 % bleibt.
In gewissem Sinne sind Testfälle und Testabdeckung Werkzeuge, mit denen Entwickler das Vertrauen in ihren eigenen Code stärken können. Allerdings sind sie nicht allmächtig. Es besteht immer die Möglichkeit, dass einige Parameter in den Testfällen fehlen. Natürlich wurde Ihr Code nicht für diese Möglichkeit geschrieben. Letztendlich kann Ihnen die Testfallabdeckung nur den Code sagen, den Sie für Sie geschrieben haben Ich habe es getestet, aber Sie können nichts gegen die Möglichkeit tun, die Sie nicht in Betracht gezogen haben. Schreiben Sie daher so viel wie möglich strengen Code, verwenden Sie beispielsweise so viel wie möglich === anstelle von ==, verwenden Sie starke Programmierstandards usw., um die potenziellen Risiken zu verringern, die durch die Annahme zu großer Parameter entstehen Reichweite.
3. Wie Code-Design das Schreiben von Testfällen vereinfacht
Das gesamte Web (nicht nur das Web) umfasst normalerweise drei Codeebenen: reine Datenverarbeitung und -berechnung, Einbeziehung von Datenbanken und Einbindung spezifischer Netzwerkprotokolle. Unter ihnen sind reine Datenoperationen hauptsächlich Funktionen oder andere Codes, die sich mit gewöhnlichen Operationen befassen. Bei Datenbanken handelt es sich um das M in MVC im herkömmlichen Sinne. Bei bestimmten Netzwerkprotokollen handelt es sich um das entsprechende C. Diese drei Tests entsprechen den ersten drei Punkten des regulären Testinhalts im ersten Abschnitt.
Da die C-Ebene normalerweise das Rendern von Seiten und die Simulation entsprechender Protokolle umfasst, kann die Komplexität des Testfallcodes, der den Controller-Code erfordert, normalerweise durch die Konzentration des Tests auf Funktionen und datenbankbezogene Codes reduziert werden . Einige aktuelle Empfehlungen für komplexere Anwendungen:
Platzieren Sie die grundlegende Überprüfung der Daten in der M-Schicht. Bei der Entwicklung mit Ruby bieten ActiveRecord und Mongoid beide sehr praktische Validierungsfunktionen.
Versuchen Sie, den Pub/Sub-Modus im Code mit einigen im ORM bereitgestellten Hooks zu verwenden, um die Kommunikation zwischen Modellen zu erreichen. Wenn A beispielsweise eine Nachricht veröffentlicht, wenn sie erstellt wird, ändert B nach dem Abhören der Nachricht einen seiner eigenen Attributwerte.
Verwenden Sie den Befehlsmodus, um einige nicht geschäftliche Funktionen aus dem System zu extrahieren, z. B. das Senden von E-Mails.
Referenz für die oben genannten Vorschläge: Laravel wisper resque
4. Idee
Der obige Inhalt vermeidet die Testfälle, die ein gemeinsames Debuggen des Front-Ends und des Backends erfordern. Der folgende Inhalt konzentriert sich hauptsächlich auf diesen Bereich. Ruby hat bereits einige elegante Implementierungen in diese Richtung. Wenn Sie interessiert sind, können Sie sich zunächst direkt an Capybara wenden.
Angesichts der Beliebtheit einer Reihe von Browsertreibern, darunter Selenium Phantomjs und Watir, die auf Ersterem basieren, ist die Steuerung des Browsers mithilfe von Code keine komplizierte Angelegenheit mehr. Basierend auf dieser Fähigkeit können Sie versuchen, Front-End-basierte Tests in vier Schritte zu unterteilen:
等待某标志性元素出现(例如等待页面载入玩,或者某个内容异步加载出现)
模拟用户操作,这里的操作包括且不局限于用户点击、用户输入
等待反馈中标志性元素出现(例如某某输入框出现)
判断内容,是否符合预期
基于这个流程,可以解决绝大多数的前端测试。但是单纯依靠这个流程任然不够,因为页面中可能出现例如验证码这样的阻碍元素,在不修改代码的前提下,可以尝试通过数据库/缓存来取到这些内容。同样,和测试接口相同,这里也涉及到在测试前数据库中插入测试数据,测试用例执行后严重数据库里面数据变化,以及全部测试完毕后删除测试数据的内容。最终导致这块测试用例代码的实现需要同时对前端后端有一定的了解。目前还在考虑在借鉴 Capybara 的基础上,设计出更加通用的方案。
最后贴一段 Capybara 的代码结束这段内容:
feature "Signing in" do background do User.make(:email => 'user@example.com', :password => 'caplin') end scenario "Signing in with correct credentials" do visit '/sessions/new' within("#session") do fill_in 'Email', :with => 'user@example.com' fill_in 'Password', :with => 'caplin' end click_button 'Sign in' expect(page).to have_content 'Success' end given(:other_user) { User.make(:email => 'other@example.com', :password => 'rous') } scenario "Signing in as another user" do visit '/sessions/new' within("#session") do fill_in 'Email', :with => other_user.email fill_in 'Password', :with => other_user.password end click_button 'Sign in' expect(page).to have_content 'Invalid email or password' end end