Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8fa448b
test: kotest mockk turbine 설정과 초기 ViewModel BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
a9d92cb
test: info/mypage 테스트를 보강하고 비동기 테스트 인프라를 안정화했어요
PeraSite Feb 14, 2026
7edc985
test: intro main map userinfo ViewModel BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
1669cb6
test: 핵심 분기 UseCase BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
f1f5235
test: ApiResult 유틸과 공통 계약 BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
266b116
test: 네트워크 래퍼와 PagingSource BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
4e32551
test: oauth와 user repository BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
ed3ef1f
test: meal menu partnership repository BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
bab627c
test: 나머지 remote repository BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
fe48d51
test: 나머지 domain usecase BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
b9580e6
test: DTO response mapper BDD 테스트를 추가했어요
PeraSite Feb 14, 2026
4bef13c
test: alarm usecase 스펙을 전체 스위트 기준으로 안정화했어요
PeraSite Feb 14, 2026
b66d890
feat: Clock의 의존성 주입을 추가했어요
PeraSite Feb 14, 2026
5302739
test: 네트워크 어댑터와 로그인 유틸 테스트를 추가했어요
PeraSite Feb 14, 2026
49dbc74
test: 누락 분기 테스트와 공용 DSL을 보강했어요
PeraSite Feb 14, 2026
9058c93
test: 유저 정보 저장 분기 조건 테스트를 보강했어요
PeraSite Feb 14, 2026
e5ccbb7
build: 로보라찌 인프라와 스크린샷 seam 추가했어요
PeraSite Feb 14, 2026
dea57ee
test: 화면 인벤토리 가드와 결정성 유틸 추가했어요
PeraSite Feb 14, 2026
b43d09c
test: 전체 화면 스냅샷 케이스와 베이스라인 추가했어요
PeraSite Feb 14, 2026
40f66a9
ci: 스크린샷 검증 워크플로우와 문서 추가했어요
PeraSite Feb 14, 2026
cebdd50
fix: 누락된 화면 스크린샷 테스트 모두 추가
PeraSite Feb 15, 2026
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
67 changes: 67 additions & 0 deletions .github/workflows/debug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,73 @@ jobs:
path: app/build/outputs/apk/release/*.apk
retention-days: 1

screenshot-verify:
name: Verify Screenshot Regression
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/buildSrc/**/*.kt') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Create Local Properties
run: touch local.properties

- name: Access Local Properties
env:
DEV_BASE_URL: ${{ secrets.DEV_BASE_URL }}
PROD_BASE_URL: ${{ secrets.PROD_BASE_URL }}
KAKAO_NATIVE_APP_KEY: ${{ secrets.KAKAO_NATIVE_APP_KEY }}
NAVER_MAPS_CLIENT_ID: ${{ secrets.NAVER_MAPS_CLIENT_ID }}
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }}
run: |
echo DEV_BASE_URL=\"$DEV_BASE_URL\" >> local.properties
echo PROD_BASE_URL=\"$PROD_BASE_URL\" >> local.properties
echo KAKAO_NATIVE_APP_KEY=$KAKAO_NATIVE_APP_KEY >> local.properties
echo NAVER_MAPS_CLIENT_ID=$NAVER_MAPS_CLIENT_ID >> local.properties
echo POSTHOG_API_KEY=$POSTHOG_API_KEY >> local.properties
echo POSTHOG_HOST=$POSTHOG_HOST >> local.properties

- name: Generate google-services.json
run: |
echo "$GOOGLE_SERVICE" > app/google-services.json.b64
base64 -d -i app/google-services.json.b64 > app/google-services.json
env:
GOOGLE_SERVICE: ${{ secrets.GOOGLE_SERVICE }}

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Verify Roborazzi
run: ./gradlew :app:verifyRoborazziDebug

- name: Upload Roborazzi outputs (failure only)
if: failure()
uses: actions/upload-artifact@v4
with:
name: roborazzi-output
path: |
app/build/outputs/roborazzi
app/build/reports/roborazzi
app/build/test-results/roborazzi
retention-days: 7

deploy-firebase:
needs: build
name: Deploy to Firebase
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@

이 프로젝트는 fastlane을 사용하여 자동화된 빌드 및 배포를 지원합니다.

## 🖼 Screenshot Testing
- [Roborazzi + Robolectric 스크린샷 회귀 테스트 가이드](docs/SCREENSHOT_TESTING.md)

**📖 상세한 가이드는 다음 문서를 참조하세요:**
👉 **[Fastlane을 이용한 배포 총 정리](.github/FASTLANE_DEPLOYMENT_GUIDE.md)**

Expand Down
36 changes: 35 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import com.github.takahirom.roborazzi.ExperimentalRoborazziApi
import java.util.Properties

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.roborazzi)
alias(libs.plugins.google.services)
alias(libs.plugins.firebase.crashlytics)
alias(libs.plugins.hilt.android)
Expand Down Expand Up @@ -134,6 +136,26 @@ android {
lint {
abortOnError = false
}

testOptions {
unitTests.isIncludeAndroidResources = true
unitTests.all {
val requestedTasks = gradle.startParameter.taskNames.joinToString(" ")
val runScreenshotCapture =
requestedTasks.contains("recordRoborazzi") || requestedTasks.contains("verifyRoborazzi")
it.useJUnitPlatform()
it.systemProperty("roborazzi.record.filePathStrategy", "relativePathFromRoborazziContextOutputDirectory")
it.systemProperty("eatssu.screenshot.capture", runScreenshotCapture.toString())
}
}
}

@OptIn(ExperimentalRoborazziApi::class)
roborazzi {
outputDir.set(file("src/test/screenshots"))
compare {
outputDir.set(file("build/outputs/roborazzi"))
}
}

dependencies {
Expand Down Expand Up @@ -180,6 +202,18 @@ dependencies {

// Testing libraries
testImplementation(libs.junit)
testImplementation(libs.kotest.runner.junit5)
testImplementation(libs.kotest.assertions.core)
testImplementation(libs.kotest.property)
testImplementation(libs.mockk)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.turbine)
testImplementation(libs.robolectric)
testImplementation(libs.roborazzi)
testImplementation(libs.roborazzi.compose)
testImplementation(libs.roborazzi.junit.rule)
testImplementation(libs.androidx.compose.ui.test.junit4)
testRuntimeOnly(libs.junit.vintage.engine)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.espresso.core)

Expand Down Expand Up @@ -269,4 +303,4 @@ dependencies {

configurations.all {
exclude(group = "io.github.fornewid", module = "naver-map-location")
}
}
5 changes: 5 additions & 0 deletions app/src/main/java/com/eatssu/android/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import java.time.Clock
import javax.inject.Singleton

@Module
Expand All @@ -17,4 +18,8 @@ object AppModule {
fun provideContext(application: Application): Context {
return application.applicationContext
}

@Provides
@Singleton
fun provideClock(): Clock = Clock.systemDefaultZone()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import android.content.Intent
import com.eatssu.android.alarm.NotificationReceiver
import dagger.hilt.android.qualifiers.ApplicationContext
import java.util.Calendar
import java.time.Clock
import javax.inject.Inject

class AlarmUseCase @Inject constructor(
@ApplicationContext private val context: Context,
private val clock: Clock,
) {

fun scheduleAlarm() {
Expand All @@ -21,13 +23,14 @@ class AlarmUseCase @Inject constructor(
)

val calendar = Calendar.getInstance().apply {
timeInMillis = clock.millis()
set(Calendar.HOUR_OF_DAY, 11)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}

if (calendar.timeInMillis <= System.currentTimeMillis()) {
if (calendar.timeInMillis <= clock.millis()) {
calendar.add(Calendar.DAY_OF_YEAR, 1)
}

Expand Down
Loading