Project 6
Using an LLM Report - Project 6-1.docx
Report Template: Evaluating LLM-Assisted Code Generation from SDS and Unit Tests
1. Introduction
Purpose: Explain the primary goal of this project or experiment. Were you testing the feasibility of LLM-assisted development, the accuracy of generated code, or its effectiveness in a TDD workflow?
Background: Briefly describe the context — the SDS and unit tests provided, the programming environment (e.g., Java, SDK dependencies), and any prior challenges motivating this approach.
2. Tools and Setup
LLM and Environment: Identify the model used (e.g., ChatGPT, GPT-5, etc.), its version, and any relevant configuration settings.
Supporting Tools: List the development tools or environments used (e.g., IntelliJ, JUnit, Git, Android Studio) and note any SDKs or APIs (such as iPal SDK).
Artifacts Provided to the LLM: Describe the specific inputs given to the LLM — such as the SDS, UML diagrams, or unit test files — and how they were formatted or presented.
3. Methodology
Prompting Strategy: Explain how you instructed the LLM to generate code. Include examples of initial prompts and follow-up instructions if iterative refinement was required.
Code–Test Cycle: Describe how you validated the LLM’s output. Did you run the generated code immediately, revise prompts, or feed test failures back into the model?
Evaluation Criteria: Define the criteria used to assess success — e.g., test pass rate, adherence to design, efficiency, readability, or maintainability.
4. Results
Functional Correctness: Report how much of the generated code passed the unit tests on the first attempt. Include percentages or counts if available.
Design Adherence: Discuss how well the generated classes and methods aligned with the specifications outlined in the SDS.
Iteration Summary: Indicate how many prompt–response cycles were needed before the code functioned correctly.
Performance: Comment on whether the generated code met expected performance or efficiency benchmarks (if applicable).
5. Analysis and Discussion
LLM Strengths: Describe where the LLM performed well — for example, in scaffolding class structures, creating helper methods, or generating testable logic.
LLM Limitations: Identify recurring issues such as misunderstanding SDK functions, generating incorrect syntax, or missing test cases.
Comparison to Manual Coding: Discuss how the LLM-based approach compared to traditional hand-coded development in terms of time, effort, and quality.
Testing and Coverage: Evaluate test coverage levels and whether the generated code satisfied most or all unit tests. Include observations about false positives or incomplete coverage.
6. Code Quality and Maintainability
Readability: Assess clarity of naming conventions, formatting, and use of comments.
Architecture: Determine whether the LLM followed object-oriented design principles and whether the resulting structure matched the SDS intent.
Maintainability: Discuss whether the code could be easily modified, extended, or reused in future projects.
7. Learning Outcomes
Student Perspective: Reflect on what was learned through using the LLM in a TDD context. Did this process clarify the relationship between design, testing, and implementation?
Skill Development: Describe improvements in understanding test-driven development, debugging, or prompt engineering.
Pedagogical Impact: Comment on how such AI-assisted methods might be incorporated into future coursework or curriculum design.
8. Ethical and Practical Considerations
Authorship and Integrity: Discuss how code attribution was handled and what constitutes original student work when using AI tools.
Reliability and Bias: Reflect on the trustworthiness of LLM-generated code and how human verification remains essential.
Responsible Use Guidelines: Propose rules or best practices for ethically integrating LLMs into programming coursework or research.
9. Conclusions
Summary of Findings: Provide a concise overview of what worked, what didn’t, and how effective the LLM was in supporting code generation from SDS and unit tests.
Recommendations for Future Work: List specific improvements — such as refining prompts, improving test clarity, or supplementing LLM-generated output with manual review.
Feasibility Statement: Conclude with your assessment: under what conditions is LLM-assisted TDD a viable or valuable approach?
10. References (if applicable)
Include references to any supporting materials, SDK documentation, or published sources used to contextualize your findings.
simulate.txt
public void simulate() { int currStop = 1; // current stop starts at 1 int time = 1; // current time boolean loopAgain = true; while (loopAgain) { loopAgain = false; // assume all customers are done boolean printed = false; // controls printing headings for (int i=0; i < custList.size(); i++) // process every customer { Customer cust = custList.get(i); // get current customer if (cust.getStatus() != Customer.CUST_EXITED) // at least one more customer to process { loopAgain = true; } // check if current customer already arrived at train and wants to enter at current stop if (cust.getStatus() == Customer.CUST_NOT_PROCESSED && cust.getArrival() <= time && cust.getEnter() == currStop) { if (!printed) System.out.println("Current Time=" + time + " Current Stop=" + currStop); System.out.println(" Customer enters train: id="+cust.getId()); cust.setStatus(Customer.CUST_ENTERED); custList.set(i, cust); // update customer list with changed status printed = true; } // check if the current customer is in train and wants to exit at current stop if (cust.getStatus() == Customer.CUST_ENTERED && cust.getExit() == currStop) { if (!printed) System.out.println("Current Time=" + time + " Current Stop=" + currStop); System.out.println(" Customer exits train: id="+cust.getId()); cust.setStatus(Customer.CUST_EXITED); custList.set(i, cust); // update customer list with changed status printed = true; } } // loop on customers if (currStop == stops) currStop = 1; // if reached last stop, reset to first stop else currStop++; // go to next stop if (printed) // if there was something printed, we made a stop { madeStops++; // update the number of stops made currTime = time; // update time to process all customers } time++; // increment current time } // while more to process }
tests.zip
bad-dup-id
1 1 2 4 1 2 3 4
bad-enter
1 1 0 2
bad-enter-exit
1 2 3 3
bad-enter2
1 1 x 2
bad-enter3
1 1 8 2
bad-exit
1 1 1 0
bad-exit2
1 1 1 x
bad-exit3
1 1 1 8
bad-id
0 1 1 2
bad-id2
x 1 1 2
bad-time
1 0 1 2
bad-time2
1 x 1 2
customer
1 1 1 2 2 2 1 3
TestCustomerAdvanced.java
TestCustomerAdvanced.java
import
static
org
.
junit
.
Assert
.
*
;
import
org
.
junit
.
Test
;
/*
* Author: Renata Rand McFadden
* Unit tests for Customer class
* Checks that Customer class exists with correct implementation of methods
*/
public
class
TestCustomerAdvanced
{
@
Test
// Test that constructor correctly updates the attributes and get method returns it:
// attribute Id
public
void
testConstructorAttributeId
()
{
String
message
=
"Id value passed to Customer Constructor does not match one returned by get method"
;
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
assertEquals
(
message
,
id
,
cust
.
getId
());
// expect same value as passed to constructor
}
@
Test
// Test that constructor correctly updates the attributes and get method returns it:
// attribute arrival
public
void
testConstructorAttributeArrival
()
{
String
message
=
"arrival value passed to Customer Constructor does not match one returned by get method"
;
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
assertEquals
(
message
,
time
,
cust
.
getArrival
());
// expect same value as passed to constructor
}
@
Test
// Test that constructor correctly updates the attributes and get method returns it:
// attribute enterStop
public
void
testConstructorAttributeEnter
()
{
String
message
=
"enter value passed to Customer Constructor does not match one returned by get method"
;
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
assertEquals
(
message
,
enter
,
cust
.
getEnter
());
// expect same value as passed to constructor
}
@
Test
// Test that constructor correctly updates the attributes and get method returns it:
// attribute exit
public
void
testConstructorAttributeExit
()
{
String
message
=
"exit value passed to Customer Constructor does not match one returned by get method"
;
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
assertEquals
(
message
,
exit
,
cust
.
getExit
());
// expect same value as passed to constructor
}
@
Test
// Test that constructor correctly updates the attributes and get method returns it:
// attribute status
public
void
testConstructorAttributeStatus
()
{
String
message
=
"status value set in Customer Constructor does not match one returned by get method"
;
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
assertEquals
(
message
,
Customer
.
CUST_NOT_PROCESSED
,
cust
.
getStatus
());
// expect status to be set to CUST_NOT_PROCESSED constant
}
@
Test
// Test that setStatus correctly updates the attributes and get method returns it:
// attribute status set to CUST_ENTERED
public
void
testConstructorMethodSetStatusValue1
()
{
String
message
=
"status value set in setStatus(int) does not match one returned by get method"
;
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
cust
.
setStatus
(
Customer
.
CUST_ENTERED
);
// set status to allowed value
assertEquals
(
message
,
Customer
.
CUST_ENTERED
,
cust
.
getStatus
());
// expect status to be set to value of CUST_ENTERED
}
@
Test
// Test that setStatus correctly updates the attributes and get method returns it:
// attribute status set to CUST_EXITED
public
void
testConstructorMethodSetStatusValue2
()
{
String
message
=
"status value set in setStatus(int) does not match one returned by get method"
;
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
cust
.
setStatus
(
Customer
.
CUST_EXITED
);
// set status to allowed value
assertEquals
(
message
,
Customer
.
CUST_EXITED
,
cust
.
getStatus
());
// expect status to be set to value of CUST_EXITED
}
@
Test
// test that if id attribute is negative throws IllegalArgumentException
public
void
testIdNegativeValue
()
{
try
{
int
id
=
-
3
;
// invalid value of id
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
fail
(
"Constructor should throw exception for invalid value of id"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if id attribute is zero throws IllegalArgumentException
public
void
testIdZeroValue
()
{
try
{
int
id
=
0
;
// invalid value of id
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
fail
(
"Constructor should throw exception for invalid value of id"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if arrival attribute is negative throws IllegalArgumentException
public
void
testArrivalNegativeValue
()
{
try
{
int
id
=
5
;
int
time
=
-
1
;
// invalid value of arrival attribute
int
enter
=
6
;
int
exit
=
8
;
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
fail
(
"Constructor should throw exception for invalid value of arrival"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if arrival attribute is zero throws IllegalArgumentException
public
void
testArrivalZeroValue
()
{
try
{
int
id
=
5
;
int
time
=
0
;
// invalid value of arrival attribute
int
enter
=
6
;
int
exit
=
8
;
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
fail
(
"Constructor should throw exception for invalid value of arrival"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if enter attribute is negative throws IllegalArgumentException
public
void
testEnterNegativeValue
()
{
try
{
int
id
=
5
;
int
time
=
10
;
int
enter
=
-
1
;
// invalid value of enter
int
exit
=
8
;
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
fail
(
"Constructor should throw exception for invalid value of enter"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if enter attribute is zero throws IllegalArgumentException
public
void
testEnterZeroValue
()
{
try
{
int
id
=
5
;
int
time
=
10
;
int
enter
=
0
;
// invalid value of enter
int
exit
=
8
;
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
fail
(
"Constructor should throw exception for invalid value of enter"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if exit attribute is negative throws IllegalArgumentException
public
void
testExitNegativeValue
()
{
try
{
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
-
1
;
// invalid value of exit
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
fail
(
"Constructor should throw exception for invalid value of exit"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if exit attribute is zero throws IllegalArgumentException
public
void
testExitZeroValue
()
{
try
{
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
0
;
// invalid value of exit
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
fail
(
"Constructor should throw exception for invalid value of enter"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if status attribute is something other than one of the constants it throws IllegalArgumentException
public
void
testStatusInvalidLess
()
{
try
{
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
// invalid value of exit
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
cust
.
setStatus
(
Customer
.
CUST_NOT_PROCESSED
-
1
);
// less than lowest constant
fail
(
"Constructor should throw exception for invalid value of enter"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
@
Test
// test that if status attribute is something other than one of the constants it throws IllegalArgumentException
public
void
testStatusInvalidHigher
()
{
try
{
int
id
=
5
;
int
time
=
10
;
int
enter
=
6
;
int
exit
=
8
;
// invalid value of exit
Customer
cust
=
new
Customer
(
id
,
time
,
enter
,
exit
);
// new instance of Customer
cust
.
setStatus
(
Customer
.
CUST_EXITED
+
1
);
// less than highest constant
fail
(
"Constructor should throw exception for invalid value of enter"
);
// if get here no exception was thrown
}
catch
(
Exception
e
)
{
if
(
e
instanceof
IllegalArgumentException
)
assertTrue
(
true
);
// if here, caught exception
else
fail
(
"Caught exception but it was not IllegalArgumentException as documented"
);
}
}
}
TestCustomerBasics.java
TestCustomerBasics.java
import
static
org
.
junit
.
Assert
.
*
;
import
java
.
lang
.
reflect
.
Constructor
;
import
java
.
lang
.
reflect
.
Field
;
import
java
.
lang
.
reflect
.
Method
;
import
org
.
junit
.
Test
;
/*
* Author: Renata Rand McFadden
* Unit tests for Customer class
* Checks that Customer class exists with correct attributes, constants, constructors, and methods
*/
public
class
TestCustomerBasics
{
@
Test
// Check that there is a class Customer
public
void
testCustomerClassExists
()
{
try
{
Class
.
forName
(
"Customer"
);
}
catch
(
ClassNotFoundException
e
)
{
fail
(
"Should have a class called Customer"
);
}
}
@
Test
// Check that Constructor exists: public Customer(int,int,int,int)
public
void
testCustomerConstructorExists
()
{
boolean
found
=
false
;
Constructor
list
[]
=
Customer
.
class
.
getConstructors
();
// get all constructors
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of Constructors
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public Customer(int,int,int,int)"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a constructor passing all four int values for attributes"
);
}
@
Test
// Check that Customer has the required attribute:
// private int Customer.id
public
void
testAttributeId
()
{
boolean
found
=
false
;
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all attributes
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"private int Customer.id"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a private id attribute of type integer"
);
}
@
Test
// Check that Customer has the required attribute:
// private int Customer.arrival
public
void
testAttributeArrival
()
{
boolean
found
=
false
;
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all attributes
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"private int Customer.arrival"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a private arrival attribute of type integer"
);
}
@
Test
// Check that Customer has the required attribute:
// private int Customer.enter
public
void
testAttributeEnter
()
{
boolean
found
=
false
;
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all attributes
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"private int Customer.enter"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a private enter attribute of type integer"
);
}
@
Test
// Check that Customer has the required attribute:
// private int Customer.exit
public
void
testAttributeExit
()
{
boolean
found
=
false
;
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all attributes
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"private int Customer.exit"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a private exit attribute of type integer"
);
}
@
Test
// Check that Customer has the required attribute:
// private int Customer.status
public
void
testAttributeStatus
()
{
boolean
found
=
false
;
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all attributes
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"private int Customer.status"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a private status attribute of type integer"
);
}
@
Test
// Check that Customer has constant called CUST_NOT_PROCESSED and set to 0
public
void
testConstantCUST_NOT_PROCESSED
()
{
boolean
found
=
false
;
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all variables
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of variables
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public static final int Customer.CUST_NOT_PROCESSED"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public constant called CUST_NOT_PROCESSED"
);
assertEquals
(
0
,
Customer
.
CUST_NOT_PROCESSED
);
// check the constant value is correct
}
@
Test
// Check that Customer has constant called CUST_ENTERED and set to 1
public
void
testConstantCUST_ENTERED
()
{
boolean
found
=
false
;
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all variables
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of variables
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public static final int Customer.CUST_ENTERED"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public constant called CUST_ENTERED"
);
assertEquals
(
1
,
Customer
.
CUST_ENTERED
);
// check the constant value is correct
}
@
Test
// Check that Customer has constant called CUST_EXITED and set to 2
public
void
testConstantCUST_EXITED
()
{
boolean
found
=
false
;
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all variables
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of variables
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public static final int Customer.CUST_EXITED"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public constant called CUST_EXITED"
);
assertEquals
(
2
,
Customer
.
CUST_EXITED
);
// check the constant value is correct
}
@
Test
// Check that Customer only has the 5 required attributes and 3 constants:
public
void
testAttributeOnlyEight
()
{
Field
list
[]
=
Customer
.
class
.
getDeclaredFields
();
// get all attributes
if
(
list
.
length
>
8
)
fail
(
"Customer class should only have five attributes and three constants defined"
);
}
@
Test
// Check that Customer has the required methods:
// public int Customer.getId()
public
void
testMethodGetId
()
{
boolean
found
=
false
;
Method
list
[]
=
Customer
.
class
.
getDeclaredMethods
();
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public int Customer.getId()"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public method called getId"
);
}
@
Test
// Check that Customer has the required methods:
// public int Customer.getEnter()
public
void
testMethodGetEnter
()
{
boolean
found
=
false
;
Method
list
[]
=
Customer
.
class
.
getDeclaredMethods
();
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public int Customer.getEnter()"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public method called getEnter"
);
}
@
Test
// Check that Customer has the required methods:
// public int Customer.getExit()
public
void
testMethodGetExit
()
{
boolean
found
=
false
;
Method
list
[]
=
Customer
.
class
.
getDeclaredMethods
();
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public int Customer.getExit()"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public method called getExit"
);
}
@
Test
// Check that Customer has the required methods:
// public int Customer.getArrival()
public
void
testMethodGetArrival
()
{
boolean
found
=
false
;
Method
list
[]
=
Customer
.
class
.
getDeclaredMethods
();
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public int Customer.getArrival()"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public method called getArrival"
);
}
@
Test
// Check that Customer has the required methods:
// public int Customer.getStatus()
public
void
testMethodGetStatus
()
{
boolean
found
=
false
;
Method
list
[]
=
Customer
.
class
.
getDeclaredMethods
();
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public int Customer.getStatus()"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public method called getStatus"
);
}
@
Test
// Check that Customer has the required methods:
// public int Customer.setStatus(int)
public
void
testMethodSetStatus
()
{
boolean
found
=
false
;
Method
list
[]
=
Customer
.
class
.
getDeclaredMethods
();
for
(
int
i
=
0
;
i
<
list
.
length
;
i
++
)
// loop through list of attributes
{
String
value
=
""
+
list
[
i
];
// convert to string
if
(
value
.
contentEquals
(
"public void Customer.setStatus(int)"
))
found
=
true
;
}
if
(
!
found
)
fail
(
"Customer class should have a public method called setStatus with integer parameter"
);
}
@
Test
// Check that Customer only has the required 6 methods
public
void
testMethodsOnlySix
()
{
Method
list
[]
=
Customer
.
class
.
getDeclaredMethods
();
// get all methods
if
(
list
.
length
>
6
)
fail
(
"Customer class should only have six methods defined"
);
}
}
TestSimulatorAdvanced.java
TestSimulatorAdvanced.java
import
static
org
.
junit
.
Assert
.
*
;
import
org
.
junit
.
After
;
import
org
.
junit
.
Before
;
import
org
.
junit
.
Test
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
ByteArrayOutputStream
;
import
java
.
io
.
File
;
import
java
.
io
.
PrintStream
;
import
java
.
util
.
ArrayList
;
public
class
TestSimulatorAdvanced
{
//create local variables for streams
private
final
ByteArrayOutputStream
outContent
=
new
ByteArrayOutputStream
();
private
final
ByteArrayOutputStream
errContent
=
new
ByteArrayOutputStream
();
@
Before
// runs before each test starts - redirects streams to local variables
public
void
setUpStreams
()
{
System
.
setOut
(
new
PrintStream
(
outContent
));
System
.
setErr
(
new
PrintStream
(
errContent
));
}
@
After
// runs after each test ends - cleans up streams to defaults
public
void
cleanUpStreams
()
{
System
.
setOut
(
null
);
System
.
setErr
(
null
);
System
.
setIn
(
System
.
in
);
//reset System.in to its original
}
@
Test
public
void
testMain
()
{
//SimulatorOld.main(null);
//MyClass.main(new String[] {"arg1", "arg2", "arg3"});
}
@
Test
// Check that get correct prompt from method getStopsFromUser
public
void
testgetStopsFromUserPrompt
()
{
String
promptMessage
=
"Enter number of stops the train has on its route (must be greater than 1):"
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"7"
.
getBytes
());
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
sim
.
getStopsFromUser
();
// call method to get number of stops
String
prompt
=
outContent
.
toString
().
trim
();
assertEquals
(
promptMessage
,
prompt
);
}
@
Test
// Test that 0 is caught as invalid input and user gets re-prompted
public
void
testgetStopsFromUserPromptLoop
()
{
String
message
=
"Invalid input, try again"
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"0\n7"
.
getBytes
());
// input 0 on first prompt and 7 on next
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
sim
.
getStopsFromUser
();
// call method to get number of stops
String
prompt
=
outContent
.
toString
().
trim
();
assertTrue
(
prompt
.
contains
(
message
));
// check that output has the error message
}
@
Test
// Test that non-integer is caught as invalid input and user gets re-prompted
public
void
testgetStopsFromUserPromptLoop2
()
{
String
message
=
"Invalid input, try again"
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"n\n7"
.
getBytes
());
// input n on first prompt and 7 on next
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
sim
.
getStopsFromUser
();
// call method to get number of stops
String
prompt
=
outContent
.
toString
().
trim
();
assertTrue
(
prompt
.
contains
(
message
));
// check that output has the error message
}
@
Test
// Test that there are two prompts on invalid input
public
void
testgetStopsFromUserPromptDouble
()
{
String
message
=
"Enter number of stops the train has on its route \\(must be greater than 1\\):"
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"n\n7"
.
getBytes
());
// input n on first prompt and 7 on next
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
sim
.
getStopsFromUser
();
// call method to get number of stops
String
output
=
outContent
.
toString
();
int
count
=
output
.
split
(
message
,
-
1
).
length
-
1
;
// count number of occurrences of prompt in output
assertEquals
(
2
,
count
);
// expect two prompt messages
}
@
Test
// Test that if user presses enter and file not exists, he gets error message
// MUST NOT HAVE customer file at C:/train/customer-data.txt
// MUST have src/customer file
public
void
testgetInputFileDefaultFail
()
{
String
message
=
"File not found, try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
sim
.
getInputFile
();
// call method to get file name
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// check that output has the error message
}
@
Test
// Test that there is correct prompt for file and enter expects that file
// MUST HAVE customer file at C:/train/customer-data.txt
// If file does not exists, the test will fail with java.util.NoSuchElementException: No line found
public
void
testgetInputFilePrompt
()
{
String
message
=
"Enter absolute path for data file or for default (C:/train/customer-data.txt) press Enter:"
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"\n"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
sim
.
getInputFile
();
// call method to get file name
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// check that output has the correct prompt
}
@
Test
// Test that if user presses enter and file not exists, he gets error message
// MUST have src/customer file
public
void
testgetInputFileNotExist
()
{
String
message
=
"File not found, try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"blahblah\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
sim
.
getInputFile
();
// call method to get file name
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// check that output has the error message
}
@
Test
// Test that if user presses enter and file not exists, there will be multiple prompts
// MUST have src/customer file
public
void
testgetInputFilePromptLoop
()
{
String
message
=
"Enter absolute path for data file or for default \\(C:\\/train\\/customer-data.txt\\) press Enter:"
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"blahblah\nblah\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
sim
.
getInputFile
();
// call method to get file name
String
output
=
outContent
.
toString
();
int
count
=
output
.
split
(
message
,
-
1
).
length
-
1
;
// count number of occurrences of prompt in output
assertEquals
(
3
,
count
);
// expect three prompt messages
}
@
Test
// Test that for id < 0, get error message
// MUST HAVE customer files at src/customer and src/bad-id
// If file does not exists, the test will fail
public
void
testCheckFileIdInvalid
()
{
String
message
=
"Data in input file is not correct. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-id\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for id non-integer gets error message
// MUST HAVE customer files at src/customer and src/bad-id2
// If file does not exists, the test will fail
public
void
testCheckFileIdInvalid2
()
{
String
message
=
"Each line must have four integers. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-id2\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for enter < 1, get error message
// MUST HAVE customer files at src/customer and src/bad-enter
// If file does not exists, the test will fail
public
void
testCheckFileEnterInvalid
()
{
String
message
=
"Data in input file is not correct. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-enter\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for enter non-integer gets error message
// MUST HAVE customer files at src/customer and src/bad-enter2
// If file does not exists, the test will fail
public
void
testCheckFileEnterInvalid2
()
{
String
message
=
"Each line must have four integers. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-enter2\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for enter > stops, get error message
// MUST HAVE customer files at src/customer and src/bad-enter3
// If file does not exists, the test will fail
public
void
testCheckFileEnterInvalid3
()
{
String
message
=
"Data in input file is not correct. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-enter3\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for exit < 1, get error message
// MUST HAVE customer files at src/customer and src/bad-exit
// If file does not exists, the test will fail
public
void
testCheckFileExitInvalid
()
{
String
message
=
"Data in input file is not correct. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-exit\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for exit non-integer gets error message
// MUST HAVE customer files at src/customer and src/bad-exit2
// If file does not exists, the test will fail
public
void
testCheckFileExitInvalid2
()
{
String
message
=
"Each line must have four integers. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-exit2\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for exit > stops, get error message
// MUST HAVE customer files at src/customer and src/bad-exit3
// If file does not exists, the test will fail
public
void
testCheckFileExitInvalid3
()
{
String
message
=
"Data in input file is not correct. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-exit3\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for duplicate id, get error message
// MUST HAVE customer files at src/customer and src/bad-dup-id
// If file does not exists, the test will fail
public
void
testCheckFileDupId
()
{
String
message
=
"Data in input file is not correct. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-dup-id\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for enter==exit, get error message
// MUST HAVE customer files at src/customer and src/bad-enter-exit
// If file does not exists, the test will fail
public
void
testCheckFileEnterExit
()
{
String
message
=
"Data in input file is not correct. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-enter-exit\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);
Simulator
sim
=
new
Simulator
();
// new instance of Simulator
File
file
=
sim
.
getInputFile
();
// call method to get file name
ArrayList
<
Customer
>
list
=
sim
.
checkFile
(
7
,
file
);
String
output
=
outContent
.
toString
();
assertTrue
(
output
.
contains
(
message
));
// passes if message is in output
assertTrue
(
"Expected list==null"
,
list
==
null
);
}
@
Test
// Test that for time < 1, get error message
// MUST HAVE customer files at src/customer and src/bad-time
// If file does not exists, the test will fail
public
void
testCheckFileTimeInvalid
()
{
String
message
=
"Data in input file is not correct. Try again."
;
ByteArrayInputStream
in
=
new
ByteArrayInputStream
(
"src/bad-time\nsrc/customer"
.
getBytes
());
// input enter
System
.
setIn
(
in
);