@startuml
skinparam classAttributeIconSize 0

	interface TestElementaire {
	    --
	    +lancer(r: ResultatTest) {Abstract}
	}
	
	class SuiteTest {
	    --
	    lancer(r: ResultatTest)
	}
	
	interface Test {
	    --
	    lancer()
	}
	
	class ResultatTest {
	    - nbTestsLaces: integer
	    - nbTestsEchecs: integer
	}
	
	abstract TE {
	    m1
	    m2
	    --
	    #preparer()
	}
	
	class TM1 {
	    --
	    tester()
	}
	
	class TM2 {
	    --
	    tester()
	}

	note right of SuiteTest
	    for(TestElementaire t : tests) {
	        t.lancer();
	    }
	end note
	
	note as noteTestElementaire
	    protected abstract void tester() throws Throwable {}

	    public void lancer(ResultatTest r) {
	        try {
	            try {
	               r.incrementer();
	                preparer();
	                tester();
	            } finally {
	                nettoyer();
	            }
	        } catch (Echec e) {
	            r.enregistrerEchec(this, e);
	        } catch () {
	            r.enregistrerEchec(this, e);
	        }
	    }
	    
	    protected static void assertTrue(boolean c) {
	        if (!c) {
	            throw new Echec();
	        }
	    }
	end note

	'SuiteTest "*" *-- "1..*" TestElementaire : Teste
	'SuiteTest o-- "*" SuiteTest
	Test "1..*" --o "*" SuiteTest
	SuiteTest .up.|> Test
	TestElementaire -u-|> Test
	TestElementaire "*" --o ResultatTest
	TE -u-|> TestElementaire
	TM1 -u-|> TE
	TM2 -u-|> TE

@enduml