danilo.pianini@unibo.itgianluca.aguzzi@unibo.itangelo.filaseta@unibo.itCompiled on: 2025-12-05 — versione stampabile
public class BuggyNumFinder {
private int smallest = Integer.MAX_VALUE;
private int largest = Integer.MIN_VALUE;
public void find(int[] numbers){
for(int n : numbers){
if(n < smallest) smallest = n;
else if(n > largest) largest = n;
}
}
public int getSmallest() {
return this.smallest;
}
public int getLargest() {
return this.largest;
}
}
import java.util.Scanner;
public class BuggyNumFinderProgram {
public static void main(String[] args){
// Lettura input dall'utente
Scanner in = new Scanner(System.in);
System.out.print("Quanti numeri? ");
int n = in.nextInt();
int[] array = new int[n];
for(int i=0; i < n; i++) {
System.out.print(i + "-esimo numero: ");
array[i] = in.nextInt();
}
in.close();
// Costruzione della UUT (Unit Under Test)
BuggyNumFinder nf = new BuggyNumFinder();
// Esecuzione della funzionalità
nf.find(array);
// Stampa dei risultati
System.out.println("Smallest: " + nf.getSmallest());
System.out.println("Largest: " + nf.getLargest());
}
}
public class BuggyNumFinderProgram2 {
public static void main(String[] args){
// Test case 1: some numbers
BuggyNumFinder numFinder = new BuggyNumFinder();
int[] input1 = new int[]{ 4, 25, 7, 9 };
numFinder.find(input1);
System.out.println("Apply to { 4, 25, 7, 9 } => " +
" - smallest: " + numFinder.getSmallest() +
" - largest: " + numFinder.getLargest());
// Test case 2: monotonically increasing sequence
int[] input2 = new int[]{ 10, 20, 30 };
numFinder.find(input2);
System.out.println("Apply to { 10, 20, 30 } => " +
" - smallest: " + numFinder.getSmallest() +
" - largest: " + numFinder.getLargest());
// Test case 3: monotonically decreasing sequence
numFinder = new BuggyNumFinder();
int[] input3 = new int[]{ 4, 3, 2, 1 };
numFinder.find(input3);
System.out.println("Apply to { 4, 3, 2, 1 } => " +
" - smallest: " + numFinder.getSmallest() +
" - largest: " + numFinder.getLargest());
}
}
public class BuggyNumFinderTest {
public static void main(String[] args){
// Test case 1: some numbers
BuggyNumFinder numFinder = new BuggyNumFinder();
int[] input1 = new int[]{ 4, 25, 7, 9 };
numFinder.find(input1);
if(!(numFinder.getSmallest() == 4 && numFinder.getLargest() == 25)){
System.out.println("Test Case #1 failed");
}
// Test case 2: monotonically increasing sequence
int[] input2 = new int[]{ 10, 20, 30 };
numFinder.find(input2);
if(!(numFinder.getSmallest() == 10 && numFinder.getLargest() == 30)){
System.out.println("Test Case #2 failed");
}
// Test case 3: monotonically decreasing sequence
numFinder = new BuggyNumFinder();
int[] input3 = new int[]{ 4, 3, 2, 1 };
numFinder.find(input3);
if(!(numFinder.getSmallest() == 1 && numFinder.getLargest() == 4)){
System.out.println("Test Case #3 failed");
}
}
}
BuggyNumFinderimport org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Assertions;
public class BuggyNumFinderJUnitTest {
BuggyNumFinder numFinder;
@BeforeEach
void setup(){
System.out.println("Setup");
numFinder = new BuggyNumFinder();
}
@Test
public void someNumbers() {
int[] input1 = new int[]{ 4, 25, 7, 9 };
numFinder.find(input1);
Assertions.assertEquals(4, numFinder.getSmallest());
Assertions.assertEquals(25, numFinder.getLargest());
}
@Test
public void positiveMonotonicallyIncreasingSequence() {
int[] input1 = new int[]{ 10, 20, 30 };
numFinder.find(input1);
Assertions.assertEquals(10, numFinder.getSmallest());
Assertions.assertEquals(30, numFinder.getLargest());
}
@Disabled // fails otherwise
@Test
public void positiveMonotonicallyDecreasingSequence() {
int[] input1 = new int[]{ 30, 20, 10 };
numFinder.find(input1);
Assertions.assertEquals(10, numFinder.getSmallest());
Assertions.assertEquals(30, numFinder.getLargest());
}
}
BuggyNumFinderorg.junit.jupiter.api.*@Test denota uno (o più) test case@BeforeEach viene eseguito prima di ogni test case
org.junit.jupiter.api.Assertions è una classe che fornisce vari metodi per esprimere asserzioni
Assertions.assertEquals(e, a) ha successo se l’oggetto atteso e è uguale all’oggetto attuale a@Test e @BeforeEach sono delle annotazioni@NomeAnnotazione
@SomeAnnotation(field1 = 88, field2 = "someString")
src/main/java/src/test/javaplugins {
id("java")
}
repositories { // Where to search for dependencies
mavenCentral()
}
dependencies {
// JUnit API and testing engine
testImplementation(platform("org.junit:junit-bom:6.0.1"))
testImplementation("org.junit.jupiter:junit-jupiter-api")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}
tasks.test {
useJUnitPlatform()
}
$ ./gradlew test
$ ./gradlew test --tests it.unibo.*.Buggy*Test # filtra i test da eseguire
org.junit.platform:junit-platform-engine:_org.junit.platform:junit-platform-launcher:_ API usata dai build tool e dagli IDE
org.junit.jupiter:junit-jupiter-api:_ API per scrivere testorg.junit.jupiter:junit-jupiter-engine:_ engine corrispondenteSomeClass, scriveremo un’altra classe SomeClassTest che conterrà metodi di test per esercitare la funzionalità offerta da SomeClassStringStringTest
src/test/java/public class StringTest {
}
String è la nostra Unit Under Test (UUT)
public class StringTest {
@Test public void checkContainsWithSubstring() {
String s = "hello world";
String substring = "world";
boolean contained = s.contains(substring);
Assertions.assertTrue(contained);
}
@Test public void checkContainsWithNoSubstring() {
String s = "hello world";
String notSubstring = "bar";
boolean contained = s.contains(notSubstring);
Assertions.assertFalse(contained);
}
}
(ISTQB Glossary) Un test case è
@Test) può esprimere uno o più test case @Test public void checkContains(){
String s = "hello world";
Assertions.assertTrue(s.contains("hello") && !s.contains("bar"));
} // questo metodo di test copre due test case
junit-jupiter-params)@ParameterizedTest @ValueSource(strings = {"hello", "world", " ", ""})
public void checkContainsParameterized(String substr){
String s = "hello world";
Assertions.assertTrue(s.contains(substr));
}
// Arrange: imposta la UUT (unit under test) e il contesto del test
String s = "hello world";
String substring = "world";
// Act: esercita la funzionalità
boolean contained = s.contains(substring);
// Assert: asserisce l'aspettativa rispetto al risultato effettivo
Assertions.assertTrue(contained);
import static org.junit.jupiter.api.Assertions.*;
public class OnAssertions {
@Test
public void workingWithAssertions() {
assertFalse("hello" == new String("hello"));
assertEquals("hello", new String("hello"));
assertNotSame("hello", new String("hello"));
assertTrue(new int[] { 1, 2, 3 } != new int[] { 1, 2, 3 });
assertNotEquals(new int[] { 1, 2, 3 }, new int[] { 1, 2, 3 });
assertArrayEquals(new int[] { 1, 2, 3 }, new int[] { 1, 2, 3 });
Object o = null;
assertNull(o);
assertNotNull(new int[]{ });
}
}
import static C.m; consente di importare nello scope il metodo statico m della classe Cimport static C.*;@BeforeAll, @AfterAll: da applicare a un metodo static; tale metodo verrà eseguito una sola volta prima o dopo l’esecuzione di tutti i test della classe di test@BeforeEach, @AfterEach: da applicare a un metodo d’istanza; tale metodo verrà eseguito prima o dopo ogni test caseSi supponga di voler progettare/implementare la funzionalità di un televisore (diciamo, una classe Tv)
Prima di implementare la classe Tv, scriviamo un test associato
public class TvTest {
@Test
public void testTurnOnWhenOff() {
Tv tv = new Tv();
Assumptions.assumeTrue(!tv.isOn());
tv.turnOn();
Assertions.assertTrue(tv.isOn());
}
}
Assumptions.assumeTrue(x) esprime una assunzione sul test, ovvero una precondizione che, se non verificata, farà sì che il test venga saltato (SKIPPED) dall’esecutore dei testAssicuriamoci che tale test compili. Per farlo, dobbiamo inizializzare la classe Tv
public class Tv {
public void turnOn(){ }
public boolean isOn(){ return false; }
}
public class Tv {
boolean on;
public void turnOn(){
this.on = true;
}
public boolean isOn(){
return this.on;
}
}
public class Tv {
boolean on;
public Tv(){
this.on = false;
}
public void turnOn(){
this.on = true;
}
public boolean isOn(){
return this.on;
}
}
public class TvTest {
Tv tv;
@BeforeEach
public void setUp(){ tv = new Tv(); }
@Test
public void testTurnOnWhenOff() {
Assumptions.assumeTrue(!tv.isOn());
tv.turnOn();
Assertions.assertTrue(tv.isOn());
}
}
turnOff()Channel e dello switch dei canali switch(Channel)danilo.pianini@unibo.itgianluca.aguzzi@unibo.itangelo.filaseta@unibo.itCompiled on: 2025-12-05 — versione stampabile