Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
c816b11
TEST: Final Integration test implemented
compactlions Dec 6, 2025
9c6d83d
Add GitHub Actions workflow for Android test coverage
compactlions Dec 6, 2025
cda7ab2
Update Gradle setup action in workflow
compactlions Dec 6, 2025
3787a49
Add build step to Android integration test workflow
compactlions Dec 6, 2025
ef50e7b
Update Java version and Gradle paths in workflow
compactlions Dec 6, 2025
35dbdf8
Update Java version from 11 to 17 in workflow
compactlions Dec 6, 2025
dd3822c
Update Gradle commands in integration test workflow
compactlions Dec 6, 2025
d144a7b
Remove build step from integration test workflow
compactlions Dec 6, 2025
4e99bf4
MINOR: code update
compactlions Dec 6, 2025
4c07ae1
Merge branch 'iteration-final-test' of https://github.com/snuhcs-cour…
compactlions Dec 6, 2025
700234c
Fix path for running Instrumentation Coverage
compactlions Dec 6, 2025
fa528f5
Update build.gradle.kts
compactlions Dec 6, 2025
38330a3
Merge branch 'iteration-final-test' of https://github.com/snuhcs-cour…
compactlions Dec 6, 2025
6b50984
Update build.gradle.kts
compactlions Dec 6, 2025
93dfa20
Update build.gradle.kts
compactlions Dec 6, 2025
a28a8c3
Update build.gradle.kts
compactlions Dec 6, 2025
1a09051
Change Android SDK installation method
compactlions Dec 6, 2025
26ff500
Add Android SDK installation steps to workflow
compactlions Dec 6, 2025
3a61a74
Refactor Android SDK installation in integration test
compactlions Dec 6, 2025
868dc18
Update Android coverage workflow configuration
compactlions Dec 6, 2025
b8181fb
Change branch for integration tests to iteration-final-test
compactlions Dec 6, 2025
05525a0
Upgrade GitHub Actions to latest versions
compactlions Dec 6, 2025
213a8b6
Update coverage report generation command
compactlions Dec 6, 2025
773fd14
Fix gradlew command path in integration test workflow
compactlions Dec 6, 2025
05ac1ac
Update build.gradle.kts
compactlions Dec 6, 2025
4ca05be
Merge branch 'iteration-final-test' of https://github.com/snuhcs-cour…
compactlions Dec 6, 2025
b94e663
MINOR: build.gradle.kts update
compactlions Dec 6, 2025
7155549
Update coverage report path in integration test workflow
compactlions Dec 6, 2025
f1a4e56
Update Gradle command for Jacoco report generation
compactlions Dec 6, 2025
1a6c2d9
Update integration test workflow for coverage artifacts
compactlions Dec 6, 2025
2142553
Update coverage artifact paths in integration test workflow
compactlions Dec 6, 2025
44681fe
Fix path for coverage.ec in workflow
compactlions Dec 6, 2025
db15bf4
Update paths for coverage.ec in workflow
compactlions Dec 6, 2025
57979d4
Update paths for coverage.ec artifact handling
compactlions Dec 6, 2025
7921472
Update build.gradle.kts
compactlions Dec 6, 2025
42b06b0
Merge branch 'iteration-final-test' of https://github.com/snuhcs-cour…
compactlions Dec 6, 2025
3e7cbb6
Update build.gradle.kts
compactlions Dec 6, 2025
95bb59e
Update build.gradle.kts
compactlions Dec 6, 2025
a58e0f2
Update build.gradle.kts
compactlions Dec 6, 2025
4777724
Add upload step for problem report artifact
compactlions Dec 6, 2025
adcb8fb
Modify artifact upload paths in integration test workflow
compactlions Dec 6, 2025
a1ad479
Update integrationtest.yml
compactlions Dec 6, 2025
6f005cd
Add step to check Jacoco report in CI workflow
compactlions Dec 6, 2025
ace1d12
Update paths for coverage and problem report artifacts
compactlions Dec 6, 2025
d459d97
Fix artifact paths in integration test workflow
compactlions Dec 6, 2025
d3e5aba
Enhance integration test workflow with debug outputs
compactlions Dec 6, 2025
6115756
Update paths for coverage and problem report artifacts
compactlions Dec 6, 2025
320b667
Update integration test workflow to build project
compactlions Dec 6, 2025
41d45d4
MINOR: Test
compactlions Dec 6, 2025
2c531e5
Merge branch 'iteration-final-test' of https://github.com/snuhcs-cour…
compactlions Dec 6, 2025
3c62780
MINOR: Test
compactlions Dec 6, 2025
e9c2193
Update Gradle command for integration tests
compactlions Dec 6, 2025
9120a38
Unused Contents Removed
compactlions Dec 7, 2025
deec2a4
MINOR: delete unused layout
compactlions Dec 7, 2025
9cd1d36
Test: for coverage
compactlions Dec 7, 2025
84929b0
TEST: for coverage
compactlions Dec 7, 2025
20a1786
TEST: For Coverage
compactlions Dec 7, 2025
bd5ac8c
Merge branch 'dev' into iteration-final-test
compactlions Dec 7, 2025
af833cd
Add ServiceLocator import to JourneyFragment
compactlions Dec 7, 2025
0e83d7b
Add ServiceLocator import to ProfileFragment
compactlions Dec 7, 2025
8192783
Add formScore LiveData to AiCoachViewModel
compactlions Dec 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/integrationtest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Android Coverage Report

on:
workflow_dispatch: # 수동 실행
push:
branches: [ "iteration-final-test" ]

jobs:
coverage:
runs-on: ubuntu-latest
defaults:
run:
working-directory: android-studio-app
steps:
- name: Checkout source
uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Upload coverage.ec
uses: actions/upload-artifact@v4
with:
name: coverage-ec
path: '**/coverage.ec'
- name: Download coverage.ec
uses: actions/download-artifact@v4
with:
name: coverage-ec
path: app/
- name: Check Jacoco report
run: ./gradlew assembleDebug

# 이미 instrumentation test를 통해 .ec 파일이 생성되어 있다고 가정
# 여기서는 리포트만 생성
- name: Generate Jacoco coverage report
run: ./gradlew pixel6DebugAndroidTestCoverage --rerun-tasks
- name: Check Jacoco report
run: |
pwd
ls -R ./
- name: Upload coverage report artifact
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: /home/runner/work/swpp-2025-project-team-16/swpp-2025-project-team-16/android-studio-app/app/build/reports/jacoco/pixel6DebugAndroidTestCoverage/html
- name: Upload problem report artifact
uses: actions/upload-artifact@v4
with:
name: problem-report
path: |
/home/runner/work/swpp-2025-project-team-16/swpp-2025-project-team-16/android-studio-app/app/build/reports/jacoco/pixel6DebugAndroidTestCoverage/html
/home/runner/work/swpp-2025-project-team-16/swpp-2025-project-team-16/android-studio-app/app/build/reports/jacoco/pixel6DebugAndroidTestCoverage/*.xml



99 changes: 78 additions & 21 deletions android-studio-app/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ plugins {
id("org.jetbrains.kotlin.android")
id("kotlin-parcelize")
id("androidx.navigation.safeargs.kotlin")
id("jacoco")


}

android {
Expand All @@ -20,6 +23,11 @@ android {
}

buildTypes {
getByName("debug") {
// 최신 AGP에서는 testCoverageEnabled 제거됨
// rootcoverage 플러그인이 커버리지 수집을 담당
isTestCoverageEnabled=true
}
debug{
isMinifyEnabled=false
}
Expand Down Expand Up @@ -49,43 +57,92 @@ android {
}

testOptions {
managedDevices {
devices {
// Kotlin DSL에서는 create<ManagedVirtualDevice>("이름") 으로 정의
create<com.android.build.api.dsl.ManagedVirtualDevice>("pixel6") {
device = "Pixel 6"
apiLevel = 33
systemImageSource = "google-atd"
}
}
}


unitTests {
isIncludeAndroidResources = true
}
}

tasks.register<JacocoReport>("jacocoAndroidTestReport") {
// 기기/에뮬레이터 테스트 실행 후 리포트 생성
dependsOn("connectedDebugAndroidTest")
dependsOn(":app:connectedDebugAndroidTest")

reports {
xml.required.set(true)
html.required.set(true)
}

// 소스 디렉터리 (Java + Kotlin)
sourceDirectories.setFrom(
files("src/main/java", "src/main/kotlin")
val fileFilter = listOf(
"**/R.class",
"**/R$*.class",
"**/BuildConfig.*",
"**/Manifest*.*",
"**/*Test*.*"
)

// 클래스 디렉터리 (AGP 버전에 따라 경로 달라질 수 있음)
classDirectories.setFrom(
fileTree("$buildDir/intermediates/classes/debug") {
exclude(
"**/R.class", "**/R$*.class",
"**/BuildConfig.*", "**/Manifest*.*",
"android/**/*.*"
)
},
fileTree("$buildDir/tmp/kotlin-classes/debug") // Kotlin 클래스
)
// Kotlin 클래스와 Java 클래스 디렉토리 모두 잡아줍니다
val kotlinDebugTree = fileTree("${project(":app").buildDir}/tmp/kotlin-classes/debug") {
exclude(fileFilter)
}
val javaDebugTree = fileTree("${project(":app").buildDir}/intermediates/javac/debug/classes") {
exclude(fileFilter)
}

// 실행 데이터 (.ec 파일)
executionData.setFrom(
fileTree("$buildDir/outputs/code_coverage/debugAndroidTest/connected") {
include("*.ec")
}

val mainSrc = "${project(":app").projectDir}/src/main/java"

sourceDirectories.setFrom(files(mainSrc))
classDirectories.setFrom(files(kotlinDebugTree, javaDebugTree))

// 여기서 coverage.ec 파일을 읽어옵니다
executionData.setFrom(fileTree("${project(":app").buildDir}/outputs/code_coverage/debugAndroidTest/connected/SM-S918N - 13") {
include("coverage.ec")
})
}

tasks.register<JacocoReport>("pixel6DebugAndroidTestCoverage") {
reports {
xml.required.set(true)
html.required.set(true)
}

val fileFilter = listOf(
"**/R.class",
"**/R$*.class",
"**/BuildConfig.*",
"**/Manifest*.*",
"**/*Test*.*"
)

// Kotlin 클래스와 Java 클래스 디렉토리 모두 잡아줍니다
val kotlinDebugTree = fileTree("${project(":app").buildDir}/tmp/kotlin-classes/debug") {
exclude(fileFilter)
}
val javaDebugTree = fileTree("${project(":app").buildDir}/intermediates/javac/debug/compileDebugJavaWithJavac/classes") {
exclude(fileFilter)
}


val mainSrc = "${project(":app").projectDir}/src/main/java"

sourceDirectories.setFrom(files(mainSrc))
classDirectories.setFrom(files(kotlinDebugTree, javaDebugTree))

// 여기서 coverage.ec 파일을 읽어옵니다
executionData.setFrom(fileTree(rootProject.projectDir) {
include("**/coverage.ec")
})

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import com.fitquest.app.model.login.SignupResponse
import okhttp3.ResponseBody.Companion.toResponseBody
import retrofit2.Response

abstract class FakeApiService: AuthApiService {
class FakeApiService: AuthApiService {
override suspend fun signup(request: SignupRequest): Response<SignupResponse> {
return when (request.name) {
"test" -> Response.success(SignupResponse("well","Not Null"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.fitquest.app

import com.fitquest.app.data.remote.DailySummaryApiService
import com.fitquest.app.model.DailySummary
import com.fitquest.app.model.MessageResponse
import org.threeten.bp.LocalDate

class FakeDailySummaryService: DailySummaryApiService {
override suspend fun getDailySummaries(): List<DailySummary> {
return listOf(DailySummary(date= LocalDate.now()))

}

override suspend fun autoGenerateDailySummaries(): MessageResponse {
return MessageResponse("well")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.fitquest.app

import com.fitquest.app.data.remote.PoseAnalysisApiService
import com.fitquest.app.model.pose.PoseUploadRequest
import com.fitquest.app.model.pose.PoseUploadResponse
import kotlinx.coroutines.delay
import retrofit2.Response

class FakePoseAnalysisApiService: PoseAnalysisApiService {
override suspend fun uploadPose(request: PoseUploadRequest): Response<PoseUploadResponse> {
delay(10000)
return Response.success(PoseUploadResponse(0,"well","poor","do right"))
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
package com.fitquest.app

import com.fitquest.app.data.remote.ScheduleApiService
import com.fitquest.app.model.AutoGenerateSchedulesResponse
import com.fitquest.app.model.Schedule
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalTime

class FakeScheduleApiService: ScheduleApiService {
override suspend fun getSchedules(status: String?): List<Schedule> {
return listOf(Schedule(scheduledDate = LocalDate.now(), startTime = LocalTime.now(), endTime = LocalTime.now(), activity = "squat"))
return listOf(Schedule(scheduledDate = LocalDate.now(), startTime = LocalTime.now(), endTime = LocalTime.now().plusHours(1), activity = "lunge",status="planned", repsTarget = 11, repsDone = 0,id=0,user=0, updatedAt = null, createdAt = null, durationDone = null),
Schedule(scheduledDate = LocalDate.now().minusDays(1), startTime = LocalTime.now(),endTime=LocalTime.now(), activity = "lunge", status = "missed",id=1),
Schedule(scheduledDate = LocalDate.now().minusDays(2), startTime = LocalTime.now(), endTime = LocalTime.now().plusHours(1), activity = "lunge",status="planned", repsTarget = 100, repsDone = 0,id=2),
Schedule(scheduledDate = LocalDate.now().plusDays(1), startTime = LocalTime.now(), endTime = LocalTime.now().plusHours(1), activity = "lunge",status="planned", repsTarget = 11, repsDone = 0,id=3))
}

override suspend fun createSchedule(schedule: Schedule): Schedule {
return Schedule(scheduledDate = LocalDate.now(), startTime = LocalTime.now(), endTime = LocalTime.now(), activity = "squat")
}

override suspend fun autoGenerateSchedules(): List<Schedule> {
return listOf(Schedule(scheduledDate = LocalDate.now(), startTime = LocalTime.now(), endTime = LocalTime.now(), activity = "squat"))

override suspend fun autoGenerateSchedules(): AutoGenerateSchedulesResponse {
return AutoGenerateSchedulesResponse(1,listOf("2025-12-07","2025-12-08"))
}

override suspend fun markMissedSchedules() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
package com.fitquest.app

import com.fitquest.app.data.remote.EndSessionRequest

import com.fitquest.app.data.remote.SessionApiService
import com.fitquest.app.data.remote.StartSessionRequest
import com.fitquest.app.model.EndSessionRequest
import com.fitquest.app.model.Session
import com.fitquest.app.model.StartSessionRequest
import org.threeten.bp.LocalDateTime
import retrofit2.Response

class FakeSessionApiService: SessionApiService {
override suspend fun getSessions(): List<Session> {
TODO("Not yet implemented")
return listOf(Session(activity = "squat",id=0, repsCount = 5, createdAt = LocalDateTime.now().minusDays(1)))
}

override suspend fun startSession(request: StartSessionRequest): Response<Session> {
TODO("Not yet implemented")
return Response.success(Session(activity = "squat",id=0))
}

override suspend fun endSession(
sessionId: Int,
request: EndSessionRequest
): Response<Session> {
TODO("Not yet implemented")
return Response.success(Session(activity = "squat", repsCount = 5))
}

}
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.fitquest.app

import com.fitquest.app.data.remote.RankResponse

import com.fitquest.app.data.remote.UserApiService
import com.fitquest.app.model.RankResponse
import com.fitquest.app.model.User
import retrofit2.Response

class FakeUserApiService: UserApiService {
override suspend fun getRankings(): Response<List<RankResponse>> {
TODO("Not yet implemented")
return Response.success(listOf(RankResponse(1,"test",100,1)))
}

override suspend fun getProfile(): User {
TODO("Not yet implemented")
return User(0,"test","test@example.com")
}
}
Loading