added tests and TOO+
This commit is contained in:
parent
fddbe1f12c
commit
58abce35ff
|
@ -529,101 +529,3 @@ public class DocumentDTO implements Serializable {
|
|||
\item nimmt Komplexität
|
||||
\item steigert Effizienz da weniger Aufrufe über Remotegrenze
|
||||
\end{itemize}
|
||||
\section{Page-Object-Pattern}
|
||||
\begin{itemize}
|
||||
\item stellt Screens der Web-App als Reihe von Objekten dar
|
||||
\item tatsächlich werden nicht alle Seiten sondern wesentliche Elemente in Objekte gekapselt
|
||||
\item eine HTML Seite wird so mitunter mit mehreren Objekten dargestellt (z.B. Header und Footer Page Object)
|
||||
\item Das Page Objekt Design eignet sich besonders gut um Selenium Tests umzusetzen
|
||||
\item Mittels der Page Objekte kann HTML Code verändert werden (Verkapselung)
|
||||
\item ermöglichen die Modellierung der Benutzeroberfläche für Tests
|
||||
\item reduziert Code duplication
|
||||
\item verbessert Testwartbarkeit und macht Tests robuster
|
||||
\end{itemize}
|
||||
\subsection{Page Object Pattern lt. Zahnlücke}
|
||||
\begin{itemize}
|
||||
\item Trennung zwischen Testmethode und Page Code
|
||||
\item Je Page eine Klasse mit Services / Operationen
|
||||
\item Return einer Operation ist ein PageObject
|
||||
\item Einfachere Wartbarkeit (Kapselung in PageObject)
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/page-object.png}
|
||||
\end{figure}
|
||||
\subsection{Beispiel aus dem Projekt}
|
||||
\subsubsection{Integration GUI Test mit Selenium}
|
||||
\begin{minted}[linenos,breaklines=true]{java}
|
||||
package at.fhj.swd.psoe.gui.pages;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import java.util.List;
|
||||
|
||||
public class DocumentsListPage extends AbstractPage {
|
||||
private List<WebElement> list;
|
||||
|
||||
public DocumentsListPage(WebDriver driver) {
|
||||
super(driver);
|
||||
}
|
||||
public List<WebElement> getList() {
|
||||
list = this.getDriver().findElements(By.xpath("//*[@id=\"documents:comdoctable_data\"]"));
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
\end{minted}
|
||||
\subsubsection{Durch Selenium getestetes Page Objekt}
|
||||
\begin{minted}[linenos,breaklines=true]{java}
|
||||
package at.fhj.swd.psoe.gui;
|
||||
|
||||
import at.fhj.swd.psoe.JdbcTestHelper;
|
||||
import at.fhj.swd.psoe.gui.pages.*;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ShowDocumentsListITCase extends AbstractChromeTest {
|
||||
final private String roleName = "ADMIN";
|
||||
private LoginPage loginPage;
|
||||
private WelcomePage welcomePage;
|
||||
private DocumentsListPage documentsListPage;
|
||||
private String baseUrl = "http://localhost:8080/chr-krenn-fhj-ws2018-swd16-pse";
|
||||
private static final JdbcTestHelper JDBC_HELPER = new JdbcTestHelper();
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() {
|
||||
super.setUp();
|
||||
JDBC_HELPER.executeSqlScript(
|
||||
"src/test/resources/sql/DocumentServiceITCase-addDocument.sql");
|
||||
loginPage = new LoginPage(this.driver, baseUrl, 60);
|
||||
welcomePage = loginPage.login("testdocument@swd.com", "admin");
|
||||
CommunitiesPage communitiesPage = welcomePage.openCommunitiesPage();
|
||||
CommunityPage communityPage = communitiesPage.openCommunityPage();
|
||||
documentsListPage = communityPage.openDocumentListPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoDocumentsListed() {
|
||||
String content = documentsListPage.getList().stream().map(x -> x.getText()).collect(Collectors.joining());
|
||||
Assert.assertTrue(content.contains("documentuser123"));
|
||||
Assert.assertTrue(content.contains("DocumentITCase1"));
|
||||
Assert.assertTrue(content.contains("DocumentITCase2"));
|
||||
}
|
||||
|
||||
@After
|
||||
@Override
|
||||
public void tearDown() {
|
||||
super.tearDown();
|
||||
JDBC_HELPER.executeSqlScript(
|
||||
"src/test/resources/sql/DocumentServiceITCase-deleteDocument.sql");
|
||||
}
|
||||
}
|
||||
\end{minted}
|
|
@ -471,17 +471,181 @@ public void saveUser(UserDTO userDTO) {
|
|||
}
|
||||
\end{minted}
|
||||
\section{Tests}
|
||||
\begin{itemize}
|
||||
\item Ziel der Tests ist es, 100\% Codecoverage im Service-Layer zu erreichen (Anforderung für unser Projekt),
|
||||
\item Private und Protected-Methoden müssen per se nicht getestet werden (Rule of Thumb),Wege zum erfolgreichen Test:
|
||||
\begin{itemize}
|
||||
\item Access-Modifier der Methoden auf public (public static) ändern,
|
||||
\item Extrahieren der Methoden in neue Klassen,
|
||||
\item Notfalls Package-Sichtbarkeit in Methode, wenn diese privat bleiben muss, Tests aber unbedingt notwendig sind.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
|
||||
\subsection{Testpyramide}
|
||||
\begin{figure}[h]
|
||||
\begin{figure}[ht!]
|
||||
\centering
|
||||
\includegraphics[width=0.9\linewidth]{pics/testpyramide}
|
||||
\caption{}
|
||||
\label{fig:testpyramide}
|
||||
\end{figure}
|
||||
\subsection{Unit}
|
||||
\subsection{Integration}
|
||||
\subsection{Selenium bzw. GUI}
|
||||
\begin{itemize}
|
||||
\item Im Build-Cycle werden zuerst Unit-Tests ausgeführt,
|
||||
\item sie befinden sich im Projekt im Ordner \textit{src/test/at/fhj/swd/psoe/service/*Test.java},
|
||||
\item ein Unit-Test muss jede Methode der Service-Klasse testen
|
||||
\item Mockito imitiert die Methoden, die von der Datenbank abhängen, da diese zu diesem Zeitpunkt noch nicht zur Verfügung steht (Build-Cycle => Compile - Unit-Tests)
|
||||
\item Im Unit-Test wird jeweils die kleinste Einheit getestet
|
||||
\item Exceptions einfach mit Mockito werfen und testen, ob sie geworfen wurden
|
||||
\end{itemize}
|
||||
\begin{minted}[linenos,breaklines=true]{java}
|
||||
@Test(expected = ServiceException.class)
|
||||
public void testGetCommunityByUserMessagesDAOException()
|
||||
{
|
||||
Mockito.when(this.userPrincipal.getId()).thenReturn(-1L);
|
||||
Mockito.when(this.communityService.loadAllCommunitiesByUser(-1L)).thenThrow(new DaoException(new RuntimeException()));
|
||||
|
||||
this.activitystreamService.getCommunityByUserMessages();
|
||||
}
|
||||
\end{minted}
|
||||
\begin{minted}[linenos,breaklines=true]{java}
|
||||
@Test
|
||||
public void getDocumentsFromCommunity_ShouldReturnDocuments() {
|
||||
Community community = Mockito.mock(Community.class);
|
||||
Mockito.when(community.getId()).thenReturn(DOCUMENTID);
|
||||
Documentlibrary doclib = Mockito.mock(Documentlibrary.class);
|
||||
|
||||
Mockito.when(community.getDocumentlibrary()).thenReturn(doclib);
|
||||
Mockito.when(doclib.getCommunity()).thenReturn(community);
|
||||
User user = Mockito.mock(User.class);
|
||||
|
||||
Mockito.when(communityDAO.findById(community.getId())).thenReturn(community);
|
||||
|
||||
List<Document> documents = prepareTwoDocuments(doclib,user);
|
||||
Mockito.when(documentDAO.findByCommunity(community)).thenReturn(documents);
|
||||
|
||||
List<DocumentDTO> documentsDTO = documentService.getDocumentsFromCommunity(community.getId());
|
||||
|
||||
Assertions.assertThat(documentsDTO)
|
||||
.usingElementComparatorIgnoringFields("user")
|
||||
.containsExactlyInAnyOrder(DocumentMapper.toDTO(documents.get(0)), DocumentMapper.toDTO(documents.get(1)));
|
||||
}
|
||||
\end{minted}
|
||||
\subsection{Integration Tests}%TODO Wolfimajer - moch fertig , bi
|
||||
\begin{itemize}
|
||||
\item testen alle Komponenten mit (Datenbank)
|
||||
\item werden im Build-Cycle erst nach dem Deployen des war-Files ausgeführt (laufende Applikation)
|
||||
\item In unserem Projekt kommt das Plugin \textit{failsafe} zum Einsatz
|
||||
\item Datenbankscripts werden separat zu den anderen Scripts ausgeführt (Datenbank vorbereiten und auf den alten Stand zurückbringen)
|
||||
\item
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.7\linewidth]{pics/test_structure}
|
||||
\caption{}
|
||||
\label{fig:teststructure}
|
||||
\end{figure}
|
||||
\end{itemize}
|
||||
\subsection{GUI-Test}
|
||||
\subsubsection{Page Object Pattern}
|
||||
\begin{itemize}
|
||||
\item stellt Screens der Web-App als Reihe von Objekten dar
|
||||
\item tatsächlich werden nicht alle Seiten sondern wesentliche Elemente in Objekte gekapselt
|
||||
\item eine HTML Seite wird so mitunter mit mehreren Objekten dargestellt (z.B. Header und Footer Page Object)
|
||||
\item Das Page Objekt Design eignet sich besonders gut um Selenium Tests umzusetzen
|
||||
\item Mittels der Page Objekte kann HTML Code verändert werden (Verkapselung)
|
||||
\item ermöglichen die Modellierung der Benutzeroberfläche für Tests
|
||||
\item reduziert Code duplication
|
||||
\item verbessert Testwartbarkeit und macht Tests robuster
|
||||
\end{itemize}
|
||||
\subsection{Page Object Pattern lt. Zahnlücke}
|
||||
\begin{itemize}
|
||||
\item Trennung zwischen Testmethode und Page Code
|
||||
\item Je Page eine Klasse mit Services / Operationen
|
||||
\item Return einer Operation ist ein PageObject
|
||||
\item Einfachere Wartbarkeit (Kapselung in PageObject)
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/page-object.png}
|
||||
\end{figure}
|
||||
\subsection{Beispiel aus dem Projekt}
|
||||
\subsubsection{Integration GUI Test mit Selenium}
|
||||
\begin{minted}[linenos,breaklines=true]{java}
|
||||
package at.fhj.swd.psoe.gui.pages;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import java.util.List;
|
||||
|
||||
public class DocumentsListPage extends AbstractPage {
|
||||
private List<WebElement> list;
|
||||
|
||||
public DocumentsListPage(WebDriver driver) {
|
||||
super(driver);
|
||||
}
|
||||
public List<WebElement> getList() {
|
||||
list = this.getDriver().findElements(By.xpath("//*[@id=\"documents:comdoctable_data\"]"));
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
\end{minted}
|
||||
\subsubsection{Durch Selenium getestetes Page Objekt}
|
||||
\begin{minted}[linenos,breaklines=true]{java}
|
||||
package at.fhj.swd.psoe.gui;
|
||||
|
||||
import at.fhj.swd.psoe.JdbcTestHelper;
|
||||
import at.fhj.swd.psoe.gui.pages.*;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ShowDocumentsListITCase extends AbstractChromeTest {
|
||||
final private String roleName = "ADMIN";
|
||||
private LoginPage loginPage;
|
||||
private WelcomePage welcomePage;
|
||||
private DocumentsListPage documentsListPage;
|
||||
private String baseUrl = "http://localhost:8080/chr-krenn-fhj-ws2018-swd16-pse";
|
||||
private static final JdbcTestHelper JDBC_HELPER = new JdbcTestHelper();
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() {
|
||||
super.setUp();
|
||||
JDBC_HELPER.executeSqlScript(
|
||||
"src/test/resources/sql/DocumentServiceITCase-addDocument.sql");
|
||||
loginPage = new LoginPage(this.driver, baseUrl, 60);
|
||||
welcomePage = loginPage.login("testdocument@swd.com", "admin");
|
||||
CommunitiesPage communitiesPage = welcomePage.openCommunitiesPage();
|
||||
CommunityPage communityPage = communitiesPage.openCommunityPage();
|
||||
documentsListPage = communityPage.openDocumentListPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoDocumentsListed() {
|
||||
String content = documentsListPage.getList().stream().map(x -> x.getText()).collect(Collectors.joining());
|
||||
Assert.assertTrue(content.contains("documentuser123"));
|
||||
Assert.assertTrue(content.contains("DocumentITCase1"));
|
||||
Assert.assertTrue(content.contains("DocumentITCase2"));
|
||||
}
|
||||
|
||||
@After
|
||||
@Override
|
||||
public void tearDown() {
|
||||
super.tearDown();
|
||||
JDBC_HELPER.executeSqlScript(
|
||||
"src/test/resources/sql/DocumentServiceITCase-deleteDocument.sql");
|
||||
}
|
||||
}
|
||||
\end{minted}
|
||||
\section{Toni FRAAGNAA}
|
||||
Den Code durchgehen - was statt null - welche Exception - logger ok?
|
||||
ob ein Throw im try Block ok ist.
|
||||
|
@ -562,8 +726,11 @@ ob ein Throw im try Block ok ist.
|
|||
|
||||
// braucht man im Controller (ViewHelper) überhaupt noch Exception Handling
|
||||
|
||||
\end{minted}
|
||||
//müssen wir die Folien genau beherrschen (Stubs vs. Mocks?)
|
||||
|
||||
//Bei welchem Goal wird was mitausgeführt? IT-Test bei mvn wildfy:run?
|
||||
|
||||
\end{minted}
|
||||
\section{Frageart Prüfung}
|
||||
Welche Fehler können bei Exception-Handling vorkommen in unserem Projekt?? – wie funktioniert es grundsätzlich in unserem Code
|
||||
|
||||
|
|
Loading…
Reference in New Issue