An application that simplifies and optimizes staff interactions and planning in a hot air baloon enterprise.
Each user is assigned a primary authentication role, such as crew, pilot, or admin. Additionally, users may temporarily acquire supplementary roles, such as maitre fondu during a flight, which should not expand their permissions.
These roles are stored in the database.
Crew members are responsible for preparing the flight, (includes arranging equipment and food for the journey). During the flight, they either follow the balloon in a vehicle or remain inside to cater to the passengers. After the theft, they are responsible for storing the equipment.. read have access to their personal data and to information relating to the flight to which they are assigned.
Pilots are the only ones legally entitled to drive a hot-air balloon. They are responsible for specialized equipment if required (high-altitude flight). Pilots have read access to their personal data and to information relating to the flight to which they are assigned.
Administrators create flights and assign staff to them. They have read/write acccess to everything.
TBD
We use emulators to integrate Firebase products in the tests.
To run the tests that use the emulators locally, you need to setup the emulators:
curl -sL https://firebase.tools | bash
firebase login
firebase emulators:start --only firestore
[!NOTE] Tests using the Firebase emulators need to be UI tests, they need to run on the Android emulator.
Here is the official documentation: https://developer.android.com/develop/ui/compose/testing#isolation
Here is the cheatsheet: https://developer.android.com/develop/ui/compose/testing-cheatsheet
There are 2 methods. An easier one, which I recommend, and a more complicated one which requires creating 2 classes for more elaborate tests.
If the component has a unique text identifier, you can use it to test it. Assume I have a button that goes back on click in the class ChatScreen.kt.
Button(onClick = "go Back", Text = "testButton")
If not you can add a test tag on it.
Button(modifier = Modifier.testTag("testButton"), onClick = "go Back")
The name of this class should be nameOfTheClassTest. Create this class where you want. For example you could create a folder Chat and put the ChatScreenTest inside.
class ChatScreenTest : TestCase(kaspressoBuilder = Kaspresso.Builder.withComposeSupport()) {
//required to test UI components
@get:Rule val composeTestRule = createComposeRule()
@Before
fun testSetup() {
val vm = ToDoViewModel()
//here ChatScreen refers to the class in app/src/main/java/ch/epfl/skysync
composeTestRule.setContent { ChatScreen(vm, mockNavActions) }
}
@Test
fun ButtonIsCorrectlyDisplayedAndhasClickAction() {
composeTestRule.onNodeWithText("testButton").assertIsDisplayed()
composeTestRule.onNodeWithText("testButton").assertHasClickAction()
composeTestRule.onNodeWithText("testButton").performClick()
//if using the test tag
composeTestRule.onNode(hasTestTag("testButton")).assertIsDisplayed()
composeTestRule.onNode(hasTestTag("testButton")).assertHasClickAction()
composeTestRule.onNode(hasTestTag("testButton")).performClick()
}
}
You can find an example testing navigation here app/src/androidTest/java/ch/epfl/skysync
First you have to add test tags to all components you want to test
The name of this class should match its counterpart. Make sure a test label is added to the class so that the test can find the location of the tested components. For example if ChatScreen is a Scaffold containg the button add the test tag on the modifier of the Scaffold.
class ChatScreen(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<ChatScreen>(
//this test tag must be set on the "top level" component (Scaffold, Surface)
semanticsProvider = semanticsProvider, viewBuilderAction = { hasTestTag("ChatScreen") }) {
// Structural elements of the UI
val testBut: KNode = child { hasTestTag("testButton") }
}
The name of this class should be nameOfTheClassTest. Create this class where you want. You could create a folder Chat and put the ChatScreenTest inside.
class ChatScreenTest : TestCase(kaspressoBuilder = Kaspresso.Builder.withComposeSupport()) {
//required to test UI components
@get:Rule val composeTestRule = createComposeRule()
/*
This rule automatic initializes lateinit properties with @MockK, @RelaxedMockK,
It gives the mocked class methods default values
*/
@get:Rule val mockkRule = MockKRule(this)
@RelaxedMockK lateinit var mockNavActions: NavigationActions
@Before
fun testSetup() {
val vm = ToDoViewModel()
//here ChatScreen refers to the class in app/src/main/java/ch/epfl/skysync
composeTestRule.setContent { ChatScreen(vm, mockNavActions) }
}
@Test
fun titleAndButtonAreCorrectlyDisplayed() { run {
//here ChatScreen refers to the class in app/src/androidTest/java/ch/epfl/skysync
onComposeScreen<ChatScreen>(composeTestRule) {
//this has to have the same name as defined in the first class
testBut {
//tests if the button is displayed
assertIsDisplayed()
//tests if the button can be clicked
assertHasClickAction()
}
}
}
}
@Test
fun goBackButtonTriggersBackNavigation() = run {
//here ChatScreen refers to the class in app/src/androidTest/java/ch/epfl/skysync
onComposeScreen<ChatScreen>(composeTestRule) {
//this has to have the same name as defined in the first class
testBut {
// arrange: verify the pre-conditions
assertIsDisplayed()
assertIsEnabled()
// act: go back !
performClick()
}
}
// assert: the nav action has been called
//go back will return a default value
verify { mockNavActions.goBack() }
confirmVerified(mockNavActions)
}
}
@get:Rule val composeTestRule = createAndroidComposeRule<MainActivity>()
* Test that a function was not called (for navigation for example)
```kotlin
verify { mockNavActions wasNot Called }
For more advanced UI testing you can refer to the tests of the bootcamp or online.
Here is how to create a simple unit test
class ExampleUnitTest {
private val testmyClass: myClass = myClass()
@Test
fun addition_isCorrect() {
val expected = 4
assertEquals(expected, testmyClass.getFour())
}
}
You can find an example in app/src/test/java/ch/epfl/skysync/database/schemas.
check connectedCheck jacocoTestReport
In order to run connectedCheck you have to launch the emulator. While in the Gradle menu (accessed by clicking on the elephant icon), you can search for tasks by clicking on the terminal icon located directly beneath "Gradle".