Dies ist eine Fortsetzung von Artikel, die ich in Wann geschrieben habe. Ich war süchtig danach, Testcode für die Verarbeitung im Zusammenhang mit der Anmeldung zu schreiben, daher werde ich ihn als Memorandum belassen. Die Erklärung des Anmeldevorgangs selbst finden Sie unter hier. Wenn Sie also nichts dagegen haben.
Wenn Sie Fehler haben, lassen Sie es mich bitte wissen (╹◡╹)
Wenn Sie diesen Artikel lesen, werden Sie (wahrscheinlich) Folgendes verstehen:
Die Umgebung ist wie folgt. Abhängige Bibliotheken usw. sind dieselben wie im vorherigen Artikel.
Der Quellcode ist auch auf GitHub zu finden.
Die Login-App ist einfach mit den folgenden Funktionen.
Ein grobes Diagramm hierzu ist in Abb. 1 dargestellt.
Abbildung 1. Verarbeitungsablauf
Die Funktion selbst ist einfach, aber wenn Sie dies und das berücksichtigen, nimmt die Anzahl der Pakete zu und es wird schwierig sein, das gesamte Bild zu erfassen. Daher zeigt Abb. 2 diejenigen, die sanft nach Rollen klassifiziert sind. ..
Abbildung 2. Übersicht über das Paket
Das Wichtigste, was Sie beim Testen beachten müssen, ob codiert oder nicht, ist, klar zu machen, was Sie überprüfen möchten. Diesmal bedeutet dies, dass die in "Spring Security" definierte Funktion wie erwartet funktioniert. Dies ist steif und etwas schwierig, die Atmosphäre zu erfassen. Machen wir es also etwas klebriger.
Wie in Abb. 3 gezeigt, ist es meiner Meinung nach leichter vorstellbar, wenn Sie "Geben Sie Ihr Bestes, wie es Spring Security verlangt" sagen.
Abbildung 3. Spring Security-Überprüfungsziel
~~ Die Charaktere sind schmutzig, also ~~ Es ist wichtig, also lassen Sie uns die obige Abbildung auch in einer Liste zeigen.
Im Folgenden erfahren Sie, wie Sie Testcode schreiben, um zu überprüfen, ob sie ordnungsgemäß funktionieren.
Beginnen wir mit einem einfachen Anmeldebildschirm. Das Bildschirmbild sollte wie in Abbildung 4 aussehen.
Abbildung 4. Anmeldebildschirm
Um zu überprüfen, ob der Anmeldevorgang ordnungsgemäß funktioniert, müssen Sie Folgendes testen:
Mit anderen Worten, es kann ausgedrückt werden als "Geht Spring Security nur wie erwartet an Menschen vorbei"?
Lassen Sie uns nun überprüfen, ob Spring Security die Aufgabe tatsächlich übernimmt.
Wenn Sie sich als einfacher Benutzer in der Datenbank anmelden, überprüfen wir zunächst, ob Sie sich anmelden können. SpringSecurity führt Folgendes als Anmeldevorgang aus.
Der Code des Prozesses selbst wird in einem anderen Artikel erklärt, daher werde ich ihn hier weglassen und mir den Testcode sofort ansehen.
LoginControllerTest.java
@DbUnitConfiguration(dataSetLoader = CsvDataSetLoader.class)
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class,
})
@AutoConfigureMockMvc
@SpringBootTest(classes = {LoginUtApplication.class})
@Transactional
public class LoginControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
Sie können sich als Benutzer anmelden, der in der ungültigen Datenbank vorhanden ist() throws Exception {
this.mockMvc.perform(formLogin("/sign_in")
.user("top_user")
.password("password"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/top_user/init"));
}
}
Ich habe den Testcode ungefähr im vorherigen Artikel geschrieben, daher werde ich hier auf die neuen Elemente eingehen.
formLogin
Ein Argument namens "formLogin" wird als Argument angegeben, das an die perfrom-Methode "von" mockMvc "übergeben werden soll. Da der Anmeldevorgang bekannt ist, können Sie sich den Betrieb in der Atmosphäre vorstellen. Die wichtigsten Punkte hier sind jedoch folgende.
Wenn Sie den Anmeldevorgang bis zu einem gewissen Grad verstehen, sollten Sie nicht gestolpert sein.
Wie von Official angegeben, leitet Spring Security Sie bei erfolgreichen / nicht erfolgreichen Anmeldungen an die angegebene URL weiter. Daher überprüfen wir hier, ob die URL des Umleitungsziels wie erwartet ist. Wie ich später ansprechen werde, reicht es aus, wenn Sie verstehen, dass Sie bei erfolgreicher Anmeldung zu der URL weitergeleitet werden, die wie der obere Bildschirm des Benutzers aussieht.
Im obigen Testcode stellt sich heraus, dass Spring Security den Benutzer durchläuft. Dies allein lässt jedoch die Möglichkeit, dass jeder willkommen und sicher sein kann. Hier werden wir überprüfen, ob die Sicherheit gewährleistet ist, dh ob Personen, die nicht durchgehen möchten, durchgelassen werden.
Das Folgende ist ein Auszug aus dem Zieltestcode.
LoginControllerTest(Auszug)
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
void Wenn ein Benutzer in der Datenbank das falsche Kennwort hat, wird er zum Fehlerbildschirm umgeleitet.() throws Exception {
this.mockMvc.perform(formLogin("/sign_in")
.user("top_user")
.password("wrongpassword"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/?error"));
}
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
void Wenn Sie sich als Benutzer anmelden, der in der Datenbank nicht vorhanden ist, werden Sie zur Fehler-URL umgeleitet.() throws Exception {
this.mockMvc.perform(formLogin("/sign_in")
.user("nobody")
.password("password"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/?error"));
}
Es gibt keinen großen Unterschied zum normalen System, aber der Punkt ist, dass das Umleitungsziel "/? Error" ist. Wenn dies ordnungsgemäß funktioniert, können Sie überprüfen, ob sich nicht nur angemeldete Benutzer anmelden können, sondern auch Benutzer, die sich nicht anmelden können, sich nicht anmelden können.
Dies ist eine minimale Stufe, aber ich konnte Testcode für den Anmeldevorgang schreiben. Die Ebenen Dao und Service überschneiden sich mit dem vorherigen Artikel, daher werde ich sie weglassen. Bei Interesse lesen Sie bitte den Quellcode.
Die Webanwendung endet übrigens nicht nach der Anmeldung, sondern verwendet während der Anmeldung verschiedene Bildschirme. Es ist jedoch sehr mühsam, sich beim Testcode des Bildschirms anzumelden, für den jedes Mal eine Anmeldung erforderlich ist, und dann den Testcode des Bildschirms zu schreiben.
Um dies zu lösen, wäre es sehr praktisch, wenn Sie manuell einen "protokollierten Status" erstellen könnten. Bevor wir uns nach dem Anmelden den Testcode auf dem Bildschirm ansehen, wollen wir uns mit dem Erstellen eines Anmeldestatus befassen.
Nun, ich habe geschrieben, dass Sie einen "protokollierten Status" erstellen sollten, aber was sollten Sie konkret tun? Geben Sie als Vorprozess eine Sitzungs-ID aus, erstellen Sie ein zu verknüpfendes Benutzerobjekt und erstellen Sie es in einer Form, die Spring Security verarbeiten kann ... selbst wenn Sie den von Spring Security nacheinander ausgeführten Prozess reproduzieren. Sie können, aber es scheint ein wenig schwierig.
Tatsächlich wird es durch Annotation verarbeitet, wie in Official eingeführt. Sie können einen simulierten Anmeldezustand erstellen, indem Sie nur ein wenig schreiben. Hier wird der "protokollierte Status" genauer als "SecurityContext" bezeichnet. Für eine Beschreibung des Kontexts sollte hier hilfreich sein.
Plötzlich wurde die Geschichte abstrakt. Abbildung 5 zeigt eine einfache grafische Darstellung des Kontexts, um die Vorstellung zu erleichtern.
Abbildung 5. Sicherheitskontext
Der Kontext ermöglicht es Ihnen, Code in demselben Zustand zu erstellen, in dem Sie auf den Bildschirm geklickt haben. Es ist bequem.
Schauen wir uns den Code an, um den Kontext tatsächlich zu erstellen.
Schauen wir uns zunächst an, wie der angemeldete Status im Testcode beschrieben wird, bevor wir auf den Inhalt eingehen. Das Schreiben des Codes, den ich ansprechen werde, erleichtert das Schreiben von Testcode, und wenn Sie zuerst die Vorzüge kennen, ist es leichter zu verstehen.
Beispiel für Testcode mit angemeldetem Status
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
@WithMockCustomUser(username="top_user", password="password")
User top wird als Ansicht in der void init-Verarbeitung übergeben() throws Exception {
this.mockMvc.perform(get("/top_user/init"))
.andExpect(view().name("top_user"));
}
Das Wichtigste ist die Annotation "WithMockCustomUser". Übergeben Sie den Benutzernamen und das Passwort als Parameter. Mit dieser Funktion können Sie als angemeldeter Benutzer den Testcode für Bildschirme ausführen, für die Sie sich anmelden müssen. Vielen Dank.
Übrigens ist diese Annotation eine benutzerdefinierte Annotation, und Sie müssen ein wenig hart arbeiten, um sie zu erstellen. Sobald Sie sie erstellt haben, können Sie sie in Anwendungen wiederverwenden, für die eine Anmeldung erforderlich ist. Lassen Sie uns unser Bestes geben, um es einfacher zu machen.
Das erste ist der Code für die Annotation "WithMockCustomUser", die zuvor geschrieben wurde. Benutzerdefinierte Anmerkungen finden Sie unter hier.
WithMockCustomUser.java
@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class)
public @interface WithMockCustomUser {
String username();
String password();
}
Die Annotation selbst ist einfach mit zwei Feldern, aber eine Annotation mit einem sehr langen Parameter namens "WithSecurityContext" hat eine schwierige Atmosphäre.
Dies ist eine Anmerkung zum Definieren von "SpringSecurityContext". Es kommt nicht sehr gut heraus, um es anders auszudrücken, es ist wie ein Memo für Spring Security, sich die Informationen "Remember this person !!" im Voraus zu merken.
Wie der Name schon sagt, definiert WithMockCustomUser nur Benutzerinformationen. Schauen wir uns also den Prozess zum Erstellen eines Kontexts an.
Es ist erfrischend zu sagen, dass es sich um eine Kontextfabrik handelt. Schauen wir uns also den tatsächlichen Code an.
WithMockCustomUserSecurityContextFactory.java
public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithMockCustomUser>{
@Autowired
private AuthenticationManager authenticationManager;
@Override
public SecurityContext createSecurityContext(WithMockCustomUser customUser) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
//Stellen Sie Token zur Authentifizierung mit Benutzername und Passwort aus
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(customUser.username(), customUser.password());
//Anmeldevorgang
Authentication auth = authenticationManager.authenticate(authToken);
context.setAuthentication(auth);
return context;
}
}
Ich habe viel Code geschrieben, aber es ist ziemlich einfach, einen protokollierten Status oder SecurityContext zu erstellen.
Das Folgende wird grob als Einzelprozess durchgeführt.
SecurityContextHolder ist ein Objekt zum Verwalten des Kontexts und verwaltet verschiedene Dinge rund um Threads, aber es liegt außerhalb der Hauptzeile, daher werde ich es dieses Mal weglassen. Ich denke, es gibt kein Problem, wenn Sie denken, dass es der Ursprung der Erstellung des Kontexts ist.
Und vor allem unterscheidet sich das "Authentifizierungstoken" hier völlig von dem, was häufig mit Cookies oder sogenannten API-Token verglichen wird. Dies scheint näher an "Hard Token" zu sein, da der Benutzername und das Passwort die Schlüssel für die Authentifizierung sind.
Es ist ein wenig abseits des Themas, aber durch Definieren einer benutzerdefinierten Anmerkung können Sie einfach einen angemeldeten Status erstellen, dh "SecurityContext", indem Sie den Benutzernamen und das Kennwort im Testcode angeben. Du hast es geschafft.
Es war ein wenig schwierig, aber jetzt, da Sie einen angemeldeten Status erstellen können, ist es viel einfacher, Testcode für Bildschirme zu schreiben, für die eine Anmeldung erforderlich ist.
Schauen wir uns nun den oberen Bildschirm für Benutzer als Beispiel für einen Bildschirm an, für den eine Anmeldung erforderlich ist. Das Bildschirmbild ist in Abbildung 6 dargestellt.
Abbildung 6. Oberer Bildschirm für Benutzer
Es ist ein einfacher Bildschirm, der nur den Benutzer begrüßt. Es ist ein Beispielbildschirm, also mach dir keine Sorgen um das Design ...
Übrigens besteht dieses Mal der Zweck darin, die Anmeldeverarbeitung zu überprüfen. In diesem Bildschirm überprüfen wir daher, ob das Folgende wie erwartet funktioniert.
Wie beim Anmeldebildschirm scheint es gut zu sein, zu überprüfen, ob Sie etwas falsch machen können. Schauen wir uns nun den eigentlichen Testcode an.
Wie beim Anmeldevorgang werden wir uns zunächst den Vorgang auf der regulären Route ansehen. Die Anzahl der zuvor eingeführten Anmerkungen hat zugenommen, sodass Sie sie meiner Meinung nach schnell verstehen können.
TopUserControllerTest.java
@DbUnitConfiguration(dataSetLoader = CsvDataSetLoader.class)
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class,
WithSecurityContextTestExecutionListener.class
})
@AutoConfigureMockMvc
@SpringBootTest(classes = {LoginUtApplication.class})
@Transactional
public class TopUserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
@WithMockCustomUser(username="top_user", password="password")
User top wird als Ansicht in der void init-Verarbeitung übergeben() throws Exception {
this.mockMvc.perform(get("/top_user/init"))
.andExpect(view().name("top_user"));
}
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
@WithMockCustomUser(username="top_user", password="password")
Der Login-Benutzername wird im Void-Init-Prozess an das Modell übergeben() throws Exception {
this.mockMvc.perform(get("/top_user/init"))
.andExpect(model().attribute("loginUsername", "top_user"));
}
}
Wie oben erwähnt, wird für WithMockCustomUser
durch Angabe des Benutzernamens und des Kennworts der angemeldete Status erstellt.
Hier können Sie sehen, dass der "WithSecurityContextTestExecutionListener", eine Klasse, die verwandt zu sein scheint, in "TestExecutionListeners" angegeben ist.
Dies ist eine Einstellung, mit der TestContextManager`` SecurityContext
verarbeiten kann.
Das Schreiben eines Kontexts für einen Kontext kann etwas verwirrend sein. Lassen Sie uns ihn daher auch hier organisieren.
Abbildung 7 zeigt eine grobe Darstellung von TestContextManager.
Abbildung 7. TestContextManager
Neben dem Kontext ist es auch für die Vor- und Nachbearbeitung verantwortlich. Wichtig ist jedoch, dass der für die Ausführung des Tests erforderliche Kontext verwaltet wird. Es mag schwierig sein, das Bild auf den ersten Blick zu erfassen, aber es ist erforderlich, vor dem Ausführen des Tests einen angemeldeten Status zu erstellen. Daher ist es gut, sich dessen bewusst zu sein.
Als nächstes wollen wir sehen, ob wir verhindern können, dass "Menschen schlechte Dinge planen". Um das zu klären, schauen wir uns noch einmal an, was das "Schlechte" bedeutet.
Da die Implementierung selbst, um das oben Genannte zu verhindern, in der Config-Klasse von Spring Security definiert ist, überprüfen wir hier, ob sie wirklich verhindert werden kann, indem eine "Testanforderung" gesendet wird.
TopUserControllerTest.java(Auszug)
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
void Nicht angemeldete Benutzer können nicht durch direkte Eingabe der URL zum oberen Bildschirm des Benutzers wechseln() throws Exception {
this.mockMvc.perform(get("/top_user/init"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/"));
}
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
@WithMockCustomUser(username="admin_user", password="password")
void Benutzer mit Administratorrechten können nicht durch direkte Eingabe der URL zum Hauptbildschirm des Benutzers wechseln.() throws Exception {
this.mockMvc.perform(get("/top_user/init"))
.andExpect(status().isForbidden());
}
Der Punkt ist, was zu tun ist, wenn Sie schlechte Dinge verhindern.
Für Benutzer, die nicht angemeldet sind, möchten wir, dass sie zum Anmeldebildschirm umgeleitet werden. Daher wird beschrieben, dass der Statuscode umgeleitet wird (beginnend mit 3) und dass das Übergangsziel der Anmeldebildschirm ist.
Und im Fall eines nicht autorisierten Benutzers (es scheint für den Administrator natürlicher zu sein, es zu sehen ...) heißt es, dass 403 Forbidden als Statuscode zurückgegeben wird.
Diese Testcodes zeigen, dass Spring Security den Job macht, den es eigentlich machen sollte. Abschließend möchte ich als Nachbearbeitung einen Blick auf die Abmeldung werfen.
Abmeldevorgang
@Test
@DatabaseSetup(value = "/controller/top/setUp/")
@WithMockCustomUser(username="top_user", password="password")
void Übergang zum Anmeldebildschirm durch Abmeldeverarbeitung() throws Exception {
this.mockMvc.perform(post("/logout")
.with(SecurityMockMvcRequestPostProcessors.csrf()))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/?logout"));
}
Der Abmeldevorgang sendet auch nur eine POST-Anfrage an die in Spring Security festgelegte Abmelde-URL, damit Sie sie in einer Atmosphäre verstehen können.
Im Gegensatz zur formLogin-Methode
gewährt eine normale POST-Anforderung jedoch kein CSRF-Token. Daher müssen Sie der Anforderung das CSRF-Token mit der Methode wirh (SecurityMockMvcRequestPostProcessors.csrf)
hinzufügen.
Dies allein scheint kein Problem zu sein, um zu überprüfen, ob der Abmeldevorgang funktioniert, aber gehen wir noch einen Schritt weiter. Wenn Sie sich abmelden, können Sie sagen, dass Sie zu "nicht angemeldet" gewechselt haben. Daher können Sie nicht zu einem Bildschirm wechseln, für den nach dem Abmelden eine Anmeldung erforderlich ist.
Ich würde mir das auch gerne ansehen, nur für den Fall. Das heißt, es ist nicht schwierig, ich habe nur die Bildschirmübergangsverarbeitung nach dem Abmelden hinzugefügt. Wenn Sie sich die Abbildungen 8 und 9 unten ansehen, sehen Sie, dass der Abmeldevorgang einen Status erstellt hat, in dem Sie nicht angemeldet sind.
Abbildung 8. Nach dem Abmelden schlägt dies fehl, da es vor dem Abmelden durchgeführt wurde.
Abbildung 9. Nach dem Abmelden werden Sie aufgefordert, sich erneut anzumelden
Es ist ein bisschen lang her, aber jetzt kann ich den Anmeldevorgang mit dem Testcode überprüfen. Ich habs gemacht. Bevor ich auf die Zusammenfassung eingehe, wird sie sich ein wenig vom Anmeldevorgang unterscheiden, aber ich möchte kurz auf den "Benutzerregistrierungsprozess" eingehen, der als Ergänzung davon abhängig ist.
In Bezug auf den Benutzerregistrierungsprozess ist der Prozess selbst fast der gleiche wie das Erstellen eines "SecurityContext". Informationen zur Implementierung finden Sie unter Quellcode.
Was wir hier behandeln möchten, ist der Validierungsprozess. Das Bild der Bewegung ist wie in 10 gezeigt.
Abbildung 10. Benutzerregistrierung
Ich bin süchtig danach, wie man den Testcode für die Validierungsverarbeitung schreibt, also schreibe ich die Punkte als Memorandum.
Testcode für den Validierungsprozess
@Test
void AuthInpuType-Fehler tritt auf, wenn eine andere Gruppe von Symbolen als der alphanumerische Bindestrich mit halber Breite unterstrichen wird() throws Exception {
this.mockMvc.perform(post("/signup/register")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("username", "<script>alert(1)</script>")
.param("rawPassword", ";delete from ut_user")
.with(SecurityMockMvcRequestPostProcessors.csrf()))
.andExpect(model().hasErrors())
.andExpect(model().attributeHasFieldErrorCode("userForm", "username", "AuthInputType"))
.andExpect(model().attributeHasFieldErrorCode("userForm", "rawPassword", "AuthInputType"));
}
@DatabaseSetup(value = "/controller/signup/setUp/")
@Test
Ein Fehler beim eindeutigen Benutzernamen tritt auf, wenn POSTing mit einem Benutzernamen durchgeführt wird, der bereits in der ungültigen Datenbank vorhanden ist() throws Exception {
this.mockMvc.perform(post("/signup/register")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("username", "test_user")
.param("rawPassword", "password")
.with(SecurityMockMvcRequestPostProcessors.csrf()))
.andExpect(model().hasErrors())
.andExpect(model().attributeHasFieldErrorCode("userForm", "username", "UniqueUsername"));
}
Es ist viel geschrieben, aber alles, was Sie tun, ist, die Werte festzulegen und die POST-Anfrage manuell zu senden. Das Wichtigste hier ist die attributeHasFieldErrorCode-Methode
.
Wir übergeben name, fieldName, error
als Argumente.
Jedes von diesen hat die folgende Entsprechung.
Wenn Sie die MVC-App berührt haben, werden Sie von Name und Feldname überrascht sein. Der Fehler kann durch Betrachten des Feldes angezeigt werden.
UserForm.java
@Data
public class UserForm {
@AuthInputType
@UniqueUsername
private String username;
@AuthInputType
private String rawPassword;
}
Hier entspricht das, was als Fehler an das Argument übergeben wird, dem Namen der Anmerkung.
Die angegebene Annotation ist eine benutzerdefinierte Annotation. Da die Annotation "Einschränkung" hinzugefügt wird, verhält sie sich wie eine Annotation "Einschränkung".
Wenn eine Einschränkungsverletzung vorliegt, erkennt BindingResult
diese als Fehler, sodass sie vom Validierungsprozess behandelt werden kann.
Weitere Informationen finden Sie unter Offiziell.
Ich habe die Korrelationsprüfung nicht vollständig verstanden und war durch den Testcode für die Kennwortübereinstimmung verwirrt. Wenn also jemand damit vertraut ist, wäre ich Ihnen dankbar, wenn Sie Informationen bereitstellen könnten. (:: ::
In Bezug auf den Anmeldevorgang ist es jetzt möglich, Testcode zu schreiben und den Vorgang zu überprüfen, obwohl dies eine grobe Idee ist. Wenn Sie sich die einfache CRUD im vorherigen Artikel und den wichtigen Anmeldevorgang in der Webanwendung in diesem Artikel ansehen, denke ich, dass Sie eine einfache Anwendung entwickeln können, während Sie den Testcode fest schreiben.
Wenn ich Code schreibe, habe ich plötzlich ein super nettes Refactoring und möchte den Code ändern, aber wenn ich Testcode wie diesen schreibe, ist das überprüfte Verhalten fehlerhaft? Ist eine Schaltfläche. Sie können dies von Anfang an überprüfen.
Darüber hinaus können Sie Tests effizient und mit garantierter Reproduzierbarkeit ausführen, ohne sich jedes Mal anmelden und auf den Bildschirm klicken zu müssen, um einen Fehlerbildschirm anzuzeigen. Es kostet viel zu lernen, wie man Testcode schreibt, aber es gibt Ihnen mehr Zeit, um lustigen Code zu schreiben. Ich denke, es ist eine gute Idee, ihn nach und nach zu integrieren, während Sie Spaß haben.
Ella, ich sage es, aber ich studiere immer noch Testcode, also würde ich gerne mein Bestes geben, um mehr zu lernen.
Recommended Posts