Uwaga! Kod z którego będziemy korzystać na zajęciach jest dostępny na branchu TestAndDebugStart w repozytorium https://github.com/WitMar/PRA2021-PRA2022 . Kod końcowy można znaleźć na branchu TestAndDebugEnd.
Jeżeli nie widzisz odpowiednich gałęzi na GitHubie wykonaj Ctr+T, a jak to nie pomoże to wybierz z menu Git->Fetch.
Co wiemy po pierwszych zajęciach:
* Projekt podzielony jest na katalogi: źródłowy - src, testowy - test, zasobów - resources.* W katalogu projektu umieszczony jest plik pom.xml odpowiadający za ustawienia Mavena, w pliku tym dodajemy odnośniki do zewnętrznych bibliotek i ustawienia budowania aplikacji.* Ustawienia loggera znajdziemy w pliku log4.properties w katalogu resources. W przypadku gdy inna biblioteka będzie potrzebowała ustawień będziemy także szukać i dodawać je w katalogu resources w odpowiednio nazwanym pliku.* Pracujemy na GIT - nowa funkcjonalność (nowy temat zajęć) zakładana jest na nowej gałęzi (ang. branch).
Przejdź do Git -> Manage Remotes
Dodaj wpis o repozytorium prowadzącego
nazwij je najlepiej jako PrzedmiotoweRepo
Wybierz Ctrl + T, aby odświeżyć zależności.
Jeżeli Ctrl+T z jakiegoś powodu nie ściągnie oczekiwanych zmian, to żeby wymusić ściągnięcie zmian wybierz Git -> fetch.
Wtedy na liście branchy w prawym dolnym rogu ekranu powinieneś widzieć gałęzie z repo przedmiotowego i ze swojego.
Przejdź na gałąź TestAndDebugStart.
Jako że dodaliśmy nowe repozytorium, możliwe, że musisz ponownie skonfigurować mavena. Przejdź do zakładki Maven i sprawdź, czy widzisz goale (Lifecycle, Plugin, Dependencies), jeżeli nie, spróbuj odświeżyć Mavena (dwie strzałki w kółko). Jeśli to nie pomoże wybierz mały plus i wskaż plik pom.xml z dysku twardego. Następnie odśwież ponownie Mavena. To powinno pomóc - sprawdź, czy twoje pliki .java mają zielone kółko obok nich w zakładce Project.
Lista skrótów IdeaJ
Alt + Enter pokaż podpowiedź rozwiązania błędu
Ctrl + W, Ctrl + Shift + W zaznaczenie całej sekcji, rozszerzenie zaznaczenia, zawężenie zaznaczenia.
Ctrl + Shift + N wyszukanie pliku po nazwie
Shift + Shift wyszukiwanie wszędzie
Alt + Insert generuj kod
Ctrl + / zakomentuj line
Ctrl + Shift + / odkomentuj linie
Ctrl + E ostatnio otwierane pliki
Ctrl + Alt + L formatuj kod
Tab, Shift+Tab wcięcie, cofnij wcięcie
Shift + F6 zmiana nazwy
Ctrl + Shift + Alt + T refaktoruj
Ctrl + Alt + M wyekstraktuj metodę
Alt + Right/Left przełączaj zakładki
Ctrl + Alt + Right / Left nawiguj wstecz / do przodu
Ctrl + (klik na nazwie metody) pokaż użycie
Ctrl + Alt + (klik na nazwie metody) pokaż implementację
Ctrl + K służy do commitowania kodu lokalnie do repozytorium
Ctrl + Shift + K służy do commitowania kodu do zewnętrznego repozytorium
Ctrl + T służy do odświeżania projektu - ściągania zmian z serwera
Uwaga!! Jeśli używasz Linuksa lub innego systemu operacyjnego innego niż Windows (lub zdalnego pulpitu), niektóre z tych skrótów mogą być już zarezerwowane w systemie, wtedy musisz zmienić ustawienia systemowe lub zmienić je w Settins->Keymap w Intellij
Wykonaj
Przedź na branch TestAndDebugStart
Wyszukaj klasę o nazwie ClassThatHaveItAll (Ctrl + Shift + N).
Zformatuj kod (Ctrl + Alt + L) - na wydziałowym linuxie ten skrót oznacza wyloguj, musisz zmienić skrót w ustawieniach systemu żeby móc go używać.
Dodaj do klasy w nagłówku linijkę
List <Long> list;
Wybierz automatyczną poprawę błędu (Alt + Enter).
Następnie wybierz (Alt + Insert) wygeneruj konstruktor, oraz settery i gettery dla klasy.
Znajdź interfejs InterfaceOne (Ctr + Shift + f). Wyszukaj użycie i implementacje metody printMe() (Ctrl + click na nazwie metody) klikając na implementacje jak i definicje metody.
Znajdź zastosowania metody ** printMe ** (Alt + F7).
Sprawdź, jak poruszać się między zakładkami (Alt + prawo / lewo) i przejść do poprzednich zmian (Ctrl + Alt + prawo / lewo).
Poprzez wybór Run -> Debug lub wybierając na klasie prawym przyciskiem myszy Debug możemy debugować nasz kod czyli uruchamiać w kontrolowany sposób, tak by móc zatrzymywać w dowolnym momencie wywołanie kodu.
Czym jest debugowanie?
Aby uruchomić kod lub uruchomić debuggowanie możesz też kliknąć na zielony trójkąt obok nazwy klasy.
Pomocne w debugowaniu są tzw. breakpointy, czyli miejsce w kodzie, w którym chcemy zatrzymać wywołanie kodu by móc podejrzeć wartości zmiennych i stan programu. Żeby dodać breakpoint klikamy obok numeru linii tak, by pojawiła się czerwona kropka.
Po kliknięciu prawym przyciskiem myszy możemy określić także specjalny warunek przy breakpoincie.
Po uruchomieniu trybu debug na dole pojawia się nam okno debugowania na którym wyświetlone są aktualne wartości zmiennych. Dodatkowo możemy wybrać przez Alt+F8 lub klikając na ikonę kalkulatora okno ewaluacji wyrażeń i wykonać ewaluację jakiegoś wyrażenia na obecnych wartościach zmiennych. Ewaluacja wyrażeń jest przydatna przy debugowaniu np. wartości list, których wartości nie jesteśmy w stanie przejrzeć pojedynczo.
Przy odpowiednich ustawieniach możliwe jest także debugowanie aplikacji działających na serwerze w czasie uruchomienia (więcej na ten temat na przyszłych zajęciach).
Wykonaj
Uruchom klasę Breakpoints. Jaki błąd wystąpił?
Uruchom debug klasy Breakpoints.
Żeby zatrzymać wywołanie dodaj breakpoint w klasie.
Użyj F8 (lub strzałka w dół na panelu debugingu) aby przejść w wywołaniu kodu linijka po linijce.
Użyj StepInto F7 (strzała w prawo-dół na panelu debugingu) aby wejść w wywołanie metody.
Znajdź i popraw błąd.
. class:: tag
Wykonaj
Uruchom klasę EvaluateExpressions. Jaki błąd wystąpił?
Ustaw breakpointa w metodzie ProcessElementAtIndex.
Otwórz okno ewaluacji wyrażeń i wpisz w nie list.get(index) .
Przechodź F9 (zielony trójkąt na panelu debug) do kolejnych wystąpień breakpointa i podglądaj wartości zmiennych.
By sprawdzić jak naprawdę wyglądają ostatnie elementy listy wpisz w oknie evaluacji następujący kod:
Collections.reverse(myList);
myList
Znajdź i popraw błąd.
Wykonaj
Uruchom klasę ConditionalBreak. Jaki błąd wystąpił?
W linii 18, ustaw zwykły breakpoint, czy łatwo jest znaleźć błąd?
Ustaw w linii 18 warunkowy breakpoint tak, by zatrzymywał się przy spełnieniu warunku !everythingIsOk.
Jak widzisz breakpoint nie działa, przenieś go do linii 19.
Uruchom kod, co wywołało błąd?
Czasami w czasie pracy jesteś zmuszony przełączyć się między różnymi zadaniami z niedokończonym kodem, a następnie wrócić do niego. IntelliJ IDEA zapewnia kilka sposobów wygodnej pracy nad kilkoma różnymi funkcjami bez utraty pracy:
utwórz nowy branch dla osobnego kodu
odłóż zmiany na półkę (ang. stash)
Nie można odkładać na półkę niewersjonowanych plików, które nie zostały dodane do kontroli wersji.
W widoku Local Changes na karcie Git pod kodem kliknij prawym przyciskiem myszy pliki lub listę zmian, które chcesz umieścić na półce, i wybierz Shelve z menu kontekstowego.
Czasami może być konieczne przywrócenie oryginalnej postaci gałęzi - HEAD, co zrobić by nie utracić w tym momencie wykonanych już zmian.
Stash działa podobnie jak shelve tylko zamiast obsługi poprzez GIT wykorzystuje IDE do przechowywania zmian.
Aby schować, zamiany lokalnie w IDE a nie w GIT wybierz Git | VCS Operations | Stash Changes, aby usunąć schowek, wybierz Git | VCS Operations | Unstash Changes.
Jeśli chcesz utworzyć nową gałąź na podstawie wybranego schowka zamiast stosować go do aktualnej gałęzi, wpisz nową nazwę w polu "As new branch".
JUnit to biblioteka służąca do pisania testów kodu. Testy mają na celu kontrolę jakości kodu, różnych ścieżek wywołań a także tego czy nowe zmiany nie wprowadzają błędów i zachowują starą funkcjonalność.
Proces budowania wersji przez Maven domyślnie uruchamia wszystkie testy znajdujące się w katalogu TEST podczas budowania pliku wykonywalnego.
Najpierw musimy dodać w pliku pom.xml zależność dla modułu testowego.
W naszym branchu jest już stworzona klasa testowa jednak by dodać nową należałoby wykonać poniższe operacje: wejść do klasy AdvanceMath i wybrać Ctrl + Shift + T , kliknąć create new Test. Aby osiągnąć to samo inaczej można wybrać nazwę klasy i kliknąć Alt + Enter i wybrać create test.
Biblioteka JUnit korzysta z tzw. adnotacji. Przed każdą metodą która ma być uruchamiana jako test umieszczamy @Test.
Inną istotną adnotacją jest @Before która pozwala nam zdefiniować operacje które będą wykonywane przed uruchomieniem każdego testu.
Przykładowa klasa testująca:
package second.junit;
import com.sun.xml.internal.ws.policy.AssertionSet;
import example.HelloWorld;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class AdvanceMathTest {
AdvanceMath math;
final static Logger logger = Logger.getLogger(AdvanceMath.class);
@Before
public void setUp(){
logger.info("Odpalam setUpa");
math = new AdvanceMath();
}
@Test
public void additionTest() {
Integer a = math.addition(1,4);
assertTrue(a==5);
}
@Test
public void additionTestString() {
long a = math.addition("1",4);
Assert.assertEquals(5L, a);
}
@Test(expected = Exception.class)
public void additionTestString2() {
int a = math.addition("a1",4);
}
}
Test możemy uruchomić klikając na klasę i wybierając run lub przez zakładkę Maven -> Test. Testy są też dodawane automatycznie przy wykonaniu Install w zakładce Mavena.
Przykłady wykorzystania biblioteki JUnit :
Polecam spojrzeć na przykłady na temat testowania list i map.
Lepszą biblioteką do pisania bardziej złożonych testów jest biblioteka AssertJ.
W pliku pom.xml dodano zależność do biblioteki assertj.
Zobacz klasę Frodo.java w katalogu test.
Dokumentacja:
Make indents inside loops and if-statements
function foo() {
if ($maybe) {
do_it_now();
again();
} else {
abort_mission();
}
finalize();
}
You can deal with curly brackets also like this:
function foo()
{
if ($maybe)
{
do_it_now();
again();
}
else
{
abort_mission();
}
finalize();
}
Use blank lines consistently and as required. Blank lines may be used for separating code lines or line groups semantically for readability.
Character count of a line should be limited for readability.
Name variables, procedures, functions in sensible way, start with small letter and introduce new word with capital letter
studentsCounter;
listIterator;
averageOverLastWeek;
findBestInClass();
computeAverage();
Name classes in sensible way, start with capital letter and introduce new word with capital letter
NightShift;
FastCar;
Name constant values with all capital letters, separate words with _
DAYS_IN_THE_WEEK();
NUMBER_OF_SHIFTS();
Using space chars in code should also be consistent in whole application. Generally, situations below are suitable for using spaces:
Between operators and operands:
a += b , c = 0; (a == b)
Between statement keywords and brackets:
if (value) {, public class A {
After ';' char in loops:
for (int i = 0; i < length; i++)
Between type casters and operands:
(int) value , (String) value