Skip to content
Permalink
Browse files

[testGeneration] Fixing platform specific tests for Umple model/ignor…

…eing unrelated targeted tests. In addition to adding a generic mechanism to write test template for elements such as attribute/method/association. This is done by declaring non-specific test as 'generic' and pass the type of Umple element you want to generically generate your test template for using <<elementType>> as a generic attribute within the test case. This aims to target large number of elements in big models and cut time/cost, also to over come some limitations of the language, in case a developer wants to write their own templates.. The type of element to be targeted for generic test generation will be narrowed down with parameters, for instance, one can write any number of test template for all attributes of type String and for method, it would be by declaring element:method and indicating the type of parameters and returned value. .details in usermanual will be provided soon
  • Loading branch information...
SultanEid committed Oct 2, 2019
1 parent c614672 commit 14730f1dcaf7ea726841ff428f2a2806d59d3e95
@@ -6,8 +6,22 @@ class UmpleTToJUnit {

members_AllTestCases <<!<</*members_AllTestCases*/>><<#

boolean skipTest = false;
boolean isConcrete = false;
for (TestCase tc : model.getTestSuite(0).getTestcases())
{#>>
{if (tc.getIsTargeted())
{
if(tc.getConcreteLanguage().equals( "PhpUnit") || tc.getConcreteLanguage().equals("RubyUnit") )
{
skipTest = true;
}
}


if (skipTest) {
//skipThisTest
}
else{ #>>
@Test
public void <<=tc.getName() >>()
{
@@ -65,6 +79,8 @@ for (TestCase tc : model.getTestSuite(0).getTestcases())
<<#
}

skipTest = false;
}

#>>!>>
}
@@ -6,8 +6,25 @@ class UmpleTToPhpUnit {

members_AllTestCases <<!<</*members_AllTestCases*/>><<#

boolean skipTest = false;
boolean isConcrete = false;
for (TestCase tc : model.getTestSuite(0).getTestcases())
{#>>
{
if (tc.getIsTargeted())
{
if(tc.getConcreteLanguage().equals( "JUnit") || tc.getConcreteLanguage().equals("RubyUnit") )
{
skipTest = true;
}
}


if (skipTest) {
//skipThisTest
}
else{

#>>
public function <<=tc.getName() >>()
{
<<#
@@ -66,5 +83,8 @@ for (TestCase tc : model.getTestSuite(0).getTestcases())
}


skipTest = false;
}

#>>!>>
}
@@ -6,8 +6,27 @@ class UmpleTToRubyUnit {

members_AllTestCases <<!<</*members_AllTestCases*/>><<#


boolean skipTest = false;
boolean isConcrete = false;

for (TestCase tc : model.getTestSuite(0).getTestcases())
{#>>
{
if (tc.getIsTargeted())
{
if(tc.getConcreteLanguage().equals( "PhpUnit") || tc.getConcreteLanguage().equals("JUnit") )
{
skipTest = true;
}
}


if (skipTest) {
//skipThisTest
}
else{

#>>
def <<=tc.getName() >> < Test::Unitt::TestCase
<<#
for (int i = 0; i<tc.getLocOrder();i++)
@@ -72,5 +91,8 @@ for (TestCase tc : model.getTestSuite(0).getTestcases())
}


skipTest = false;
}

#>>!>>
}
@@ -51,7 +51,9 @@ class TestCase {

name;
int locOrder;

String concreteLanguage = "";
boolean isTargeted = false;
boolean isConcrete = false;

0..1 testcase -- * TestInitialization inits;
0..1 testcase -- * Assertion assertions;
@@ -467,6 +467,31 @@ for ( Token st : t.getSubTokens())

{

if(st.getName().equals("isTargeted"))
{
if(st.getValue("isTargeted") != null)
{

aTestCase.setIsTargeted(true);
aTestCase.setConcreteLanguage(st.getValue("isTargeted"));
System.out.println( aTestCase.getConcreteLanguage());

}


}

if(st.getName().equals("isConcrete"))
{
if(st.getValue("isConcrete") != null)
{
aTestCase.setIsConcrete(true);
aTestCase.setIsTargeted(true);
aTestCase.setConcreteLanguage(st.getValue("isTargeted"));
}

}

if(st.getName().equals("initialization"))
{
//system.out.println("\tInitlocOrder");
@@ -25,7 +25,7 @@ thenCont: (THEN:)? [[testCase]]*


//testCase : test [~testCaseName] {( [[initialization]] | [[methodCall]] | [[assertions]] | [[testInitAtt]] | [[comment]] )* }
testCase : test [~testCaseName] {( [[initialization]] | [[assertion]] | [[testInitAtt]] | [[comment]] )* }
testCase : [=abstract:abstract]? [=isConcrete:concrete]? [=isTargeted:JUnit|PhpUnit|RubyUnit]? test [~testCaseName] {( [[initialization]] | [[assertion]] | [[testInitAtt]] | [[comment]] )* }
initialization : [~identifier] [~name] OPEN_ROUND_BRACKET [[parameter]]* CLOSE_ROUND_BRACKET ;
//testinitAtt
testInitAtt : [~identifier] [~attributeName] = [[pValue]] ;
@@ -320,6 +320,11 @@ class UmpleInternalParser
analyzeClassTestCase(token,aClass);
}

else if (token.is("genericTestCase"))
{
analyzeClassGenericTestCase(token,aClass);
}

else if (token.is("testSequence"))
{
analyzeClassTestSequence(token,aClass);
@@ -975,6 +975,103 @@ private void analyzeClassTestSequence(Token token, UmpleClass aClass) {

}

///// generic methods

private void analyzeClassGenericTestCase(Token token, UmpleClass aClass){
String element = "";

if (token.getValue("genericElement").equals("attribute"))
{
element = "attribute";
}

else if (token.getValue("genericElement").equals("method"))
{
element = "method";
}

else {
getParseResult().addErrorMessage(new ErrorMessage(new ErrorType(6020,4, "Generic Test element is not recognized. ", ""), aClass.getPosition(0)));
}




if (element.equals("attribute"))
{
for (Attribute att : aClass.getAttributes())
{
String code = token.getValue("code");
//boolean isPascaled = false;
char preChar = '-';
int indexOfNonPascaledElement = 0;
int preCharIndex = 0;
//StringBuilder code = new StringBuilder(token.getValue("code"));
String pascalRegex = "[a-zA-Z0-9]<<attribute>>";
String nonPascalRegex = "[=|(|!|\\s]<<attribute>>";
//String lookAheadAssertion = "\\w(?= {attribute})";
Pattern pattern = Pattern.compile(pascalRegex);
Matcher matcher = pattern.matcher(code);
Pattern nonPattern = Pattern.compile(nonPascalRegex);
Matcher nonMatcher =nonPattern.matcher(code);
//preChar = code.substring(matcher.start()-2, matcher.start()-1).;
while(matcher.find())
{
int startIndex = matcher.start();
int endIndex = matcher.end();
preCharIndex = matcher.start();
preChar = code.charAt(preCharIndex);
if(Character.isLetter(preChar)){ // to check that the attribute is within a method call such as getId and has no white spaces or Java characters: ex get<<attribute>>
String tempGroup = matcher.group();
String tempReplacement = tempGroup.replace("<<attribute>>", StringFormatter.toPascalCase(att.getName()));
code = code.replace(tempGroup,tempReplacement);
}
while (nonMatcher.find()) // this loop fins matches of attribute that are not part of a methodCall example : getValue(<<attribute>>) it is rather a parameter in this case or String tempAtt = <<attribute>>
{
String tempGroup = nonMatcher.group();
String tempReplacement = tempGroup.replace("<<attribute>>", att.getName());
code = code.replace(tempGroup,tempReplacement);
}

//isPascaled = false;

}

//System.out.println(code);

UmpleTestCase uTestCase = new UmpleTestCase(token.getValue("testCaseName")+"_"+att.getName(),0);
TestAction aTestAction = new TestAction("genericAttribute", code.toString(), "generic", 0);

uTestCase.addTestAction(aTestAction);
uTestCase.setLocOrder(uTestCase.getLocOrder()+1);
aClass.addUmpleTestCase(uTestCase);
matcher.reset();

//System.out.println(uTestCase.getTestAction(0).getActionCode());
}




}



if (element.equals("method"))
{
for (Method meth : aClass.getMethods())
{
UmpleTestCase uTestCase = new UmpleTestCase(token.getValue("testCaseName")+"_"+meth.getName(),0);
TestAction aTestAction = new TestAction("genericAttribute", token.getValue("code"), "generic", 0);
aTestAction.setActionCode(aTestAction.getActionCode().replace("{method}", meth.getName()));
uTestCase.addTestAction(aTestAction);
uTestCase.setLocOrder(uTestCase.getLocOrder()+1);
aClass.addUmpleTestCase(uTestCase);
}
}
}





@@ -29,7 +29,7 @@ associationClassDefinition : associationClass [name] { [[associationClassContent
enumerationDefinition : enum [name] { [enumValue](, [enumValue])* }

// The following items can be found inside the body of classes or association classes
classContent- : [[comment]] | [[innerClass]] | [[mixsetDefinition]] | [[distributable]] | [[proxyPattern]] | [[classDefinition]] | [[trace]] | [[emitMethod]] | [[templateAttributeDefinition]] | [[primitiveDefinition]] | [[portDefinition]] | [[portBindingDefinition]] | [[position]] | [[displayColor]] | [[abstract]] | [[keyDefinition]] | [[softwarePattern]] | [[depend]] | [[symmetricReflexiveAssociation]] | [[attribute]] | [[testCase]] | [[testSequence]] | [[stateMachine]] | [[activeMethodDefinition]] | [[inlineAssociation]] | [[concreteMethodDeclaration]] | [[constantDeclaration]] | [[modelConstraint]] | [[invariant]] | ; | [[enumerationDefinition]] | [[exception]] | [[extraCode]]
classContent- : [[comment]] | [[innerClass]] | [[mixsetDefinition]] | [[distributable]] | [[proxyPattern]] | [[classDefinition]] | [[trace]] | [[emitMethod]] | [[templateAttributeDefinition]] | [[primitiveDefinition]] | [[portDefinition]] | [[portBindingDefinition]] | [[position]] | [[displayColor]] | [[abstract]] | [[keyDefinition]] | [[softwarePattern]] | [[depend]] | [[symmetricReflexiveAssociation]] | [[attribute]] | [[testCase]] | [[genericTestCase]] | [[testSequence]] | [[stateMachine]] | [[activeMethodDefinition]] | [[inlineAssociation]] | [[concreteMethodDeclaration]] | [[constantDeclaration]] | [[modelConstraint]] | [[invariant]] | ; | [[enumerationDefinition]] | [[exception]] | [[extraCode]]
associationClassContent- : [[comment]] | [[classDefinition]] | [[position]] | [[displayColor]] | [[invariant]] | [[softwarePattern]] | [[depend]] | [[association]] | [[inlineAssociation]] | [[singleAssociationEnd]] | [[attribute]] | [[stateMachine]] | ; | [[extraCode]]
innerClass : [[innerStaticClass]] | [[innerNonStaticClass]]
innerStaticClass : static [[classDefinition]]
@@ -81,6 +81,9 @@ interfaceTest : test [~testName] ;
testSequence : testSequence [~sequenceName] { [[testSequenceEntry]] }
testSequenceEntry : [~name] ( -> [~name] )* ;

// Generic test case rules
genericTestCase : generic test [~testCaseName] OPEN_ROUND_BRACKET [~genericElement] CLOSE_ROUND_BRACKET { ( [**code] )* }




@@ -0,0 +1,25 @@

class Person {

id;
name;
address;


generic test checkifLogged(attribute){
Person p1 ( "S1425", "John", "Ottawa") ;
String valueToCheck = p1.get<<attribute>>();
ps1.getValue(<<attribute>>);
boolean isLogged = p1.checkIsLogged(valueToCheck);
assertTrue(logged == "true");
}





String returnSumOfValues (int x, int y) { return x+y;}

}


@@ -310,6 +310,18 @@ public void testSequence_noTestCasesTest()

}

@Test
public void genericTestCaseTest()
{
language = "Test";
assertUmpleTemplateFor("test/GenericTestCase.ump","test/testGenericTestCase.test.txt");
//Assert.assertEquals(true, (new File(pathToInput + "/test/test/NNToManyAssociation_ModelTest.umpt")).exists());
createUmpleSystem(pathToInput, "test/GenericTestCase.ump");
Assert.assertEquals(true, (new File(pathToInput + "/test/test/GenericTestCase_ModelTest.umpt")).exists());


}




0 comments on commit 14730f1

Please sign in to comment.
You can’t perform that action at this time.