28
Μηχανική Λογισμικού ΙΙ Μηχανική Λογισμικού ΙΙ Έλεγχος Λογισμικού Έλεγχος Λογισμικού JUNIT – TDD JUNIT – TDD TFD + Refactoring TFD + Refactoring Παναγιώτης Σφέτσος, PhD http://aetos.it.teithe.gr/~sfetsos/ [email protected]

Μηχανική Λογισμικού ΙΙ Έλεγχος Λογισμικού JUNIT – TDD TFD + Refactoring

  • Upload
    ula

  • View
    49

  • Download
    0

Embed Size (px)

DESCRIPTION

Μηχανική Λογισμικού ΙΙ Έλεγχος Λογισμικού JUNIT – TDD TFD + Refactoring. Παναγιώτης Σφέτσος , PhD http://aetos.it.teithe.gr/~sfetsos/ [email protected]. Σκοπός. Έλεγχοι παντού και πάντα ( Testing… ) Test Driven Development ( TDD ) Test-First Design ( TFD ) + Refactoring. - PowerPoint PPT Presentation

Citation preview

Page 1: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Μηχανική Λογισμικού ΙΙΜηχανική Λογισμικού ΙΙ

Έλεγχος ΛογισμικούΈλεγχος Λογισμικού

JUNIT – TDDJUNIT – TDDTFD + RefactoringTFD + Refactoring

Παναγιώτης Σφέτσος, PhDhttp://aetos.it.teithe.gr/~sfetsos/

[email protected]

Page 2: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Σκοπός Σκοπός

2Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Έλεγχοι παντού και πάντα (Testing…)

Test Driven Development (TDD)

Test-First Design (TFD) + Refactoring

Page 3: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Εισαγωγή Εισαγωγή

3Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Έλεγχοι μονάδας (Unit testing): Από τους προγραμματιστές Αυτοματοποιημένοι, ώστε να μπορούν να εκτελούνται επαναληπτικά Εργαλείο JUNIT

Έλεγχοι ενσωμάτωσης (Integration testing): Από τους προγραμματιστές, καθώς ενσωματώνουν νέο κώδικα στη βάση

κώδικα. Αυτοματοποιημένοι, ώστε να μπορούν να εκτελούνται επαναληπτικά

Λειτουργικοί έλεγχοι συστήματος (Functional Testing): Εκτελούνται συνήθως από κάποια εξωτερική ομάδα ελέγχου Συνήθως είναι αυτοματοποιημένοι και έχουν την μορφή μαύρου κουτιού

Έλεγχοι αποδοχής (Acceptance testing): Διενεργούνται από τον πελάτη ή τους εκπροσώπους του, στο δικό τους

χώρο. Συνήθως είναι αυτοματοποιημένοι και έχουν την μορφή μαύρου κουτιού

Page 4: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Unit Testing – JUNITUnit Testing – JUNIT

4Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Έλεγχοι μονάδας (Unit Testing) Το πλαίσιο ελέγχου (testing framework) - JUNIT

Java και JUNIT (Beck και Gamma) – Ανοικτός κώδικας

Η επιτυχία ή αποτυχία μιας δοκιμής στον κώδικα απεικονίζεται με την βοήθεια μιας πράσινηςπράσινης ή κόκκινηςκόκκινης μπάραςμπάρας αντίστοιχα (στο γραφικό περιβάλλον).

Δημιουργούμε μια κλάση ελέγχου | δοκιμήςμια κλάση ελέγχου | δοκιμής για κάθε κλάση του προγράμματος της εφαρμογής

Κάθε κλάση ελέγχου περιέχει ένα σύνολο από μεθόδους δοκιμήςμεθόδους δοκιμής, που ελέγχουν τη σωστή λειτουργία των μεθόδων των κλάσεων της εφαρμογής

Πλεονεκτήματα: Σωστός κώδικας, Τεκμηρίωση

Page 5: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Integration Testing – JUNITIntegration Testing – JUNIT

5Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Έλεγχοι ενσωμάτωσης (Integration testing)

Εργαλείο συνήθως το JUNIT

Δημιουργία ακολουθιών δοκιμών ακολουθιών δοκιμών (test suites)

Οι ακολουθίες δοκιμών ενσωματώνουν όλες τις κλάσεις δοκιμών σε μία κλάση και με τον τρόπο αυτό εκτελούνται ταυτόχρονα όλα τα τεστ των κλάσεων της βάσης κώδικα

Εύκολα και γρήγορα γνωρίζουμε ότι όλες οι κλάσεις μας λειτουργούν σωστά.

Page 6: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Εγκατάσταση του Εγκατάσταση του JUNIT (DOS) - 1JUNIT (DOS) - 1

6Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Κατεβάστε το εργαλείο junit από τη διεύθυνση http://www.junit.org/

Κάντε unzip των αρχείων στον επιθυμητό κατάλογο (συνήθως c:\junitx.xx.x )

Ανοίξτε το παράθυρο γραμμής εντολών (Command Prompt)

Ορίστε ως κατάλογο εργασίας τον φάκελο bin της έκδοσης java που έχετε: cd C:\Program Files\Java\jdk1.6.0_01\bin

• Με την CLASSPATH ορίστε την διαδρομή όπου βρίσκεται

αποθηκευμένο το junitjunit..jarjar καθώς και την διαδρομή όπου βρίσκονται αποθηκευμένες οι κλάσεις δοκιμών που θέλετε να τρέξετε. (π.χ C:\Program Files\Java\jdk1.6.0_01\bin>

set classpath=%classpath%;C:\junit3.8.1\junit.jar; C:\junit3.8.1;

Page 7: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Εγκατάσταση του Εγκατάσταση του JUNIT (DOS) - 2JUNIT (DOS) - 2

Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Για να εμφανιστεί το παράθυρο του JUNIT και να δείτε το

αποτέλεσμα της κλάσης δοκιμής σας εκτελέστε την

ακόλουθη εντολή: C:\Program Files\Java\jdk1.6.0_01\bin>

και μετάκαι μετά::

για text: 1) java junit.textui.TestRunner junit.samples.AllTests

για γραφική: 2) java junit.awtui.TestRunner junit.samples.AllTests

για swing: 3) java junit.swingui.TestRunnerjunit.samples.AllTests

Όπου: AllTests στην συγκεκριμένη περίπτωση είναι μία κλάση δοκιμής

που υπάρχει στον φάκελο junit\samples του junitx.x. Αντί για AllTests

εσείς θα γράφετε το όνομα της δικής σας κλάσης δοκιμής, έχοντας βέβαια

ορίσει την κατάλληλη διαδρομή στην μεταβλητή CLASSPATH.

7

Page 8: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

8Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Εγκατάσταση του Εγκατάσταση του JUNIT (DOS) - 3JUNIT (DOS) - 3

Page 9: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Το πλαίσιο δοκιμών - Το πλαίσιο δοκιμών - JUNITJUNIT

9Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Το εργαλείο JUNIT αποτελείται από: πακέτα κώδικα της Java (packages) και περιπτώσεις ελέγχου (test cases) του κώδικα.

• Εκτελεί τους ελέγχους κώδικα σε επίπεδο μονάδαςεπίπεδο μονάδας (unit testing)

ή μαζικήςμαζικής επεξεργασίαςεπεξεργασίας (batch mode-integration testing) – για ελέγχους ενσωμάτωσης.

• Εκτελεί τους ελέγχους σαν τις μεθόδους μιας κλάσης.

• Πολλαπλές περιπτώσεις ελέγχου εκτελούνται με την μορφή ακολουθιών δοκιμώνακολουθιών δοκιμών (test suites)

• Η περίπτωση ελέγχου περίπτωση ελέγχου (test case) περιέχει μια συλλογή ελέγχων μονάδων ενώ η ακολουθία δοκιμών ακολουθία δοκιμών (test suite) περιέχει ένα σύνολο από περιπτώσεις ελέγχου.

Page 10: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Το μοντέλο Το μοντέλο JUNITJUNIT

10Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Page 11: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Κανόνες και ορισμοίΚανόνες και ορισμοί - 1 - 1

11Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Ο κύκλος ζωής της περίπτωσης ελέγχου (TestCase lifecycle)

1. setUp() // αρχικοποίηση

2. testXXX() // η μέθοδος ελέγχου ΧΧΧ

3. tearDown() // η διαγραφή

• Επανάληψη βημάτων 1 έως 3 για κάθε μέθοδο testXXX …

• Οι setUp() και tearDown() μπορούν να υπερφορτωθούν (overriding), αλλά και να παραληφθούν ανάλογα τις περιπτώσεις.

Page 12: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Κανόνες και ορισμοίΚανόνες και ορισμοί - 2 - 2

12Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Απλό Test: Εισάγουμε το πλαίσιο των Εισάγουμε το πλαίσιο των junit-testsjunit-tests

Ορίζουμε μια υποκλάση της Ορίζουμε μια υποκλάση της TestCase.TestCase.

Υπερφορτώνουμε ή παραλείπουμε τις μεθόδους setUp() & tearDown().

Ορίζουμε μια ή περισσότερες Ορίζουμε μια ή περισσότερες δημόσιες μεθόδους δημόσιες μεθόδους testXXX()testXXX(). .

Ελέγχουμε το αντικείμενο/α που λαμβάνουν μέρος στην δοκιμή.

Βεβαιώνουμε Βεβαιώνουμε ((assertassert)) τα τα αποτελέσματα. αποτελέσματα.

import junit.framework.TestCase;import junit.framework.TestCase;

class Calculator {

public double add(double x, double y) {

return (x+y);}

}

public class TestCalculator extends TestCasepublic class TestCalculator extends TestCase

{

public void testAdd()public void testAdd()

{

Calculator calc = new Calculator();

double result = calc.add(50,10);

assertEquals(60, result,0);assertEquals(60, result,0);

} }

Page 13: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Κανόνες και ορισμοίΚανόνες και ορισμοί - 3 - 3

13Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Test με την χρήση της Test suit()

Εισάγουμε το πλαίσιο των Εισάγουμε το πλαίσιο των junit-testsjunit-tests

Ορίζουμε μια υποκλάση της Ορίζουμε μια υποκλάση της TestCase.TestCase.

Υπερφορτώνουμε ή παραλείπουμε τις μεθόδους setUp() & tearDown().

Ορίζουμε μια ή περισσότερες δημόσιες Ορίζουμε μια ή περισσότερες δημόσιες μεθόδους μεθόδους testXXX()testXXX(). .

Ελέγχουμε το αντικείμενο/α που λαμβάνουν μέρος στην δοκιμή.

Βεβαιώνουμε Βεβαιώνουμε ((assertassert)) τα αποτελέσματα. τα αποτελέσματα.

Ορίζουμε μια στατική μέθοδο την Ορίζουμε μια στατική μέθοδο την suite()suite()

Ορίζουμε μια ακολουθία δοκιμών Ορίζουμε μια ακολουθία δοκιμών ((TestSuiteTestSuite))

Προαιρετικά ορίζουμε μια μέθοδο Προαιρετικά ορίζουμε μια μέθοδο main()main() για για να τρέξουμε την να τρέξουμε την TestCaseTestCase

package TestExamples;

import java.util.*;

import junit.framework.*;

public class FirstTest extends TestCase {

public void testEmptyCollection() {

Collection collection = new ArrayList();

assertTrue(collection.isEmpty()); }

public static Test suite() {

return new TestSuite(FirstTest.class); }

public static void main(String args[]) {

junit.textui.TestRunner.run(suite()); } }

Page 14: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Ο έλεγχος με την Ο έλεγχος με την Test suit Test suit και και main()main()

14Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

// 1 – εισάγουμε τις κλάσεις και μεθόδους της junit package TestExamples;import java.util.*;import junit.framework.*;

// 2 – δημιουργούμε την υποκλάση της TestCase: public class FirstTest extends TestCase {

// 3 – γράφουμε μια μέθοδο ελέγχου για να βεβαιωθούμε (to assert) : public void testEmptyCollection() { Collection collection = new ArrayList(); assertTrue(collection.isEmpty()); //τις εντολές assert θα δούμε αναλυτικά παρακάτω }

// 4 – γράφουμε μια ακολουθία δοκιμών που περιέχει όλες τις μεθόδους TestXXX: public static Test suite() { return new TestSuite(FirstTest.class); } // 5 – γράφουμε την main() για να τρέξουμε το τεστ με αποτελέσματα σε μορφή κειμένου: public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } }

Page 15: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Εκτελεστές Ελέγχων (Εκτελεστές Ελέγχων (TestRunnersTestRunners))

15Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

6 – τρέχουμε το τεστ στο παράθυρο του dos (αποτελέσματα σε μορφή κειμένου):java TestExamples.FirstTest

Το αποτέλεσμα θα είναι:. Time: 0 OK (1 tests)

7 – τρέχουμε το τεστ για αποτελέσματα σε γραφική μορφή – πράσινη μπάρα:

java junit.swingui.TestRunner TestExamples.FirstTest

Page 16: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Οι Εντολές - Οι Εντολές - assertassert

16Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

assertTrue(boolean condition)assertFalse(boolean condition)

assertEquals(Object expected, Object actual)Χρησιμοποιεί την equals() σύγκριση (ίδια αντικείμενα)

assertSame(Object expected, Object actual)assertNotSame(Object expected, Object actual)Χρησιμοποιεί την == σύγκριση (δύο αντικείμενα αναφέρονται στο ίδιο)

assertEquals(float expected, float actual, float tolerance)

assertNull(Object o)assertNotNull(Object o)

fail(String message), κλπ……….. - Απλό μήνυμα λάθους

Page 17: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Ενοποιημένο περιβάλλον ανάπτυξης κώδικα java και τεστ ελέγχων (JUNIT). To περιβάλλον διατίθεται δωρεάν και μπορείτε να το κατεβάσετε από την διεύθυνση www.jcreator.com/download.htm

JCreatorJCreator - 1 - 1

Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

17

Page 18: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

JCreatorJCreator - 2 - 2

Για να τρέχουμε τις κλάσεις δοκιμών με το JUnit μέσα από τον JCreator κάνουμε τις παρακάτω ρυθμίσεις :

Προσθέτουμε την διαδρομή του Junit στο παρακάτω πεδίο του μενού Project: ProjectProject SettingsJDK version j2sdk1.4.2_04editadd add archivec:\junitx.x\junit.jar

Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

18

Page 19: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

JCreatorJCreator - 3 - 3

Προσθέτουμε την διαδρομή CLASSPATH του junit.jar στο παρακάτω πεδίο του μενού Build ή Run: Build Runtime Configuration default edit Run Application default edit Parameters Γράφουμε: -classpath ".;c:\junit3.8.1\junit.jar" junit.swingui.TestRunner

Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

19

Page 20: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Παράδειγμα – 2οΠαράδειγμα – 2ο

20Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Θέλουμε να κατασκευάσουμε την κλάση - box που θα περιλαμβάνει μέθοδο υπολογισμού του όγκου του. Για να βεβαιωθούμε ότι η μέθοδος δουλεύει σωστά θα γράψουμε ένα τεστ ελέγχου (μέθοδο), ορίζοντας δύο διαφορετικά αντικείμενα. Γράφουμε πρώτα τον κώδικα της κλάσης :

import junit.framework.*;public class BoxTest extends TestCase {

class Box { double width; double height; double depth; / / O κατασκευαστής της Box. Box(double x, double y, double z) { width = x; height = y; depth = z; }

//υπολογισμός και επιστροφή του όγκου double volume() {return width * height * depth; }}

Page 21: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Παράδειγμα – 2ο (συνέχεια..)Παράδειγμα – 2ο (συνέχεια..)

21Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Το τεστ ελέγχου public void testAdd() { // δήλωση, και αρχικοποίηση των αντικειμένων box Box mybox1 = new Box(10, 20, 15); Box mybox2 = new Box(3, 6, 9); double vol; // λήψη όγκου του πρώτου box vol = mybox1.volume(); assertTrue(vol == 3000.00); // λήψη όγκου του δευτέρου box vol = mybox2.volume(); assertTrue(vol == 162.00); }}

Page 22: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Παράδειγμα – 2ο (συνέχεια..)Παράδειγμα – 2ο (συνέχεια..)

22Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Page 23: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Παράδειγμα – Παράδειγμα – 33ο ο

import junit.framework.*;

public class SimpleTest extends TestCase { protected int fValue1; protected int fValue2;

protected void setUp() { fValue1= 2; fValue2= 3; }

public void testAdd() { double result= fValue1 + fValue2; assertTrue(result == 6); }

public void testDivideByZero() { int zero= 0; int result= 8/(zero); }

public void testEquals() { assertEquals(12, 12); assertEquals(12L, 12L); assertEquals(new Long(12), new Long(12)); assertEquals("Size", 12, 13); assertEquals("Capacity", 12.0, 11.00, 0.0); }}

Θα ελέγξουμε τους τύπους και τιμές μερικών μεταβλητών – Κάνουμε λάθη σε διαίρεσημε το μηδέν, αλλά και σε τιμές μεταβλητών

23Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Page 24: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Παράδειγμα – Παράδειγμα – 33ο ο

24Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Page 25: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Παράδειγμα – Παράδειγμα – 33ο (Με τις διορθώσεις) ο (Με τις διορθώσεις)

import junit.framework.*;

public class SimpleTest extends TestCase { protected int fValue1; protected int fValue2;

protected void setUp() { fValue1= 2; fValue2= 3; }

public void testAdd() { double result= fValue1 + fValue2; assertTrue(result == 5); }

public void testDivideByZero() { int zero= 0; try{ int result= 8/(zero); } catch (Exception e) {} } public void testEquals() { assertEquals(12, 12); assertEquals(12L, 12L); assertEquals(new Long(12), new Long(12)); assertEquals("Size", 12, 12); assertEquals("Capacity", 12.0, 12.00, 0.0); }}

Διορθώνουμε τα λάθη, προσθέτουμε try – catch για να πιάσουμε το λάθος της διαίρεσης με το μηδέν.

25Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Page 26: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Παράδειγμα – Παράδειγμα – 33ο (Με τις διορθώσεις) ο (Με τις διορθώσεις)

26Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Page 27: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Δημιουργία ακολουθίας δοκιμών για όλες τις κλάσειςΔημιουργία ακολουθίας δοκιμών για όλες τις κλάσεις

27Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ

Αν θέλουμε την main() για εκτέλεση όλων των κλάσεων δοκιμών, τότε δημιουργούμε την παρακάτω ξεχωριστή κλάση:

import junit.framework.Test;import junit.framework.TestSuite;public class AllMyTestSuite { // Δημιουργούμε το σετ των τεστ (πλήθος 3) public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(A_Test.class); suite.addTestSuite(BoxTest.class); suite.addTestSuite(SimpleTest.class); return suite; } //Τρέχουμε το σετ των τεστ (suite) public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } }

Page 28: Μηχανική Λογισμικού  ΙΙ Έλεγχος Λογισμικού JUNIT  – TDD TFD + Refactoring

Δημιουργία ακολουθίας δοκιμών για όλες τις κλάσειςΔημιουργία ακολουθίας δοκιμών για όλες τις κλάσεις

28Παναγιώτης Σφέτσος, Μηχανική Λογισμικού ΙΙ