added tests and TOO+

This commit is contained in:
Moser Benjamin 2019-03-06 01:29:57 +01:00
parent fddbe1f12c
commit 58abce35ff
3 changed files with 172 additions and 103 deletions

View File

@ -528,102 +528,4 @@ public class DocumentDTO implements Serializable {
\item kapselt und versteckt
\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}
\end{itemize}

View File

@ -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.
@ -561,9 +725,12 @@ ob ein Throw im try Block ok ist.
// dependency Injection
// braucht man im Controller (ViewHelper) überhaupt noch Exception Handling
//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

BIN
pse.pdf

Binary file not shown.