쪽지발송 성공
Click here
재능넷 이용방법
재능넷 이용방법 동영상편
가입인사 이벤트
판매 수수료 안내
안전거래 TIP
재능인 인증서 발급안내

🌲 지식인의 숲 🌲

🌳 디자인
🌳 음악/영상
🌳 문서작성
🌳 번역/외국어
🌳 프로그램개발
🌳 마케팅/비즈니스
🌳 생활서비스
🌳 철학
🌳 과학
🌳 수학
🌳 역사
해당 지식과 관련있는 인기재능

소개안드로이드 기반 어플리케이션 개발 후 서비스를 하고 있으며 스타트업 경험을 통한 앱 및 서버, 관리자 페이지 개발 경험을 가지고 있습니다....

안녕하세요.신호처리를 전공한 개발자 입니다. 1. 영상신호처리, 생체신호처리 알고리즘 개발2. 안드로이드 앱 개발 3. 윈도우 프로그램...

 안녕하세요. 안드로이드 기반 개인 앱, 프로젝트용 앱부터 그 이상 기능이 추가된 앱까지 제작해 드립니다.  - 앱 개발 툴: 안드로이드...

Flutter 테스트 자동화: mockito와 bloc_test

2024-12-24 03:18:22

재능넷
조회수 58 댓글수 0

Flutter 테스트 자동화: mockito와 bloc_test 완벽 가이드 🚀

 

 

안녕하세요, 플러터 개발자 여러분! 오늘은 정말 흥미진진한 주제로 여러분과 함께할 거예요. 바로 'Flutter 테스트 자동화: mockito와 bloc_test'에 대해 깊이 파헤쳐볼 거랍니다. 이 글을 읽고 나면 여러분도 테스트 자동화의 달인이 될 수 있을 거예요! 😎

먼저, 우리가 왜 테스트 자동화에 관심을 가져야 하는지 아시나요? 바로 앱의 품질을 높이고, 버그를 줄이고, 개발 시간을 단축시킬 수 있기 때문이에요. 특히 Flutter 앱 개발에서는 이런 테스트 자동화가 더욱 중요하답니다.

그럼 이제부터 본격적으로 시작해볼까요? 준비되셨나요? 자, 출발~! 🏁

1. Flutter 테스트의 기초 🧱

Flutter 테스트에 대해 이야기하기 전에, 먼저 테스트가 뭔지 알아야겠죠? 테스트란 간단히 말해서 우리가 만든 코드가 제대로 작동하는지 확인하는 과정이에요. 마치 요리사가 음식을 만들고 맛을 보는 것처럼요!

Flutter에서는 크게 세 가지 유형의 테스트를 할 수 있어요:

  • 단위 테스트 (Unit Tests)
  • 위젯 테스트 (Widget Tests)
  • 통합 테스트 (Integration Tests)

오늘은 이 중에서 단위 테스트와 위젯 테스트에 초점을 맞출 거예요. 특히 mockito와 bloc_test 라이브러리를 사용해서 말이죠!

🤔 잠깐, 왜 테스트가 중요할까요?

1. 버그를 빨리 발견할 수 있어요.

2. 코드의 품질을 높일 수 있어요.

3. 리팩토링을 안전하게 할 수 있어요.

4. 개발 속도를 높일 수 있어요.

자, 이제 기초는 알았으니 본격적으로 mockito와 bloc_test에 대해 알아볼까요? 준비되셨나요? 그럼 고고! 🚀

2. Mockito: 가짜를 만들어 진짜를 테스트하자! 🎭

여러분, 'mockito'라는 말 들어보셨나요? 아마 처음 들으시는 분들도 많을 거예요. Mockito는 Dart와 Flutter에서 사용되는 강력한 모킹(mocking) 프레임워크예요. 모킹이 뭐냐고요? 쉽게 말해서 '가짜'를 만드는 거예요!

예를 들어볼까요? 여러분이 카페 주인이라고 상상해보세요. 새로운 바리스타를 고용하기 전에 그 사람의 실력을 테스트하고 싶어요. 그런데 실제 손님들을 대상으로 테스트하면 위험하겠죠? 그래서 여러분은 '가짜 손님'을 고용해서 테스트를 해요. 이게 바로 모킹의 개념이에요!

🎭 Mockito의 주요 기능:

1. 객체의 행동을 시뮬레이션할 수 있어요.

2. 메소드 호출을 검증할 수 있어요.

3. 특정 상황에서의 반환값을 지정할 수 있어요.

4. 예외 상황을 테스트할 수 있어요.

자, 이제 Mockito를 사용해보겠습니다! 먼저 pubspec.yaml 파일에 Mockito를 추가해야 해요.


dependencies:
  flutter:
    sdk: flutter
  mockito: ^5.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.0.0

이제 간단한 예제를 통해 Mockito를 사용해볼까요?


import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

// 테스트할 클래스
class Cat {
  String sound() => "Meow";
  bool eatFood(String food) => true;
}

// Mock 클래스 생성
class MockCat extends Mock implements Cat {}

void main() {
  group('Cat', () {
    MockCat cat;

    setUp(() {
      cat = MockCat();
    });

    test('should return "Meow" when sound() is called', () {
      when(cat.sound()).thenReturn("Meow");
      expect(cat.sound(), "Meow");
    });

    test('should return true when eatFood() is called with any food', () {
      when(cat.eatFood(any)).thenReturn(true);
      expect(cat.eatFood("Fish"), true);
      expect(cat.eatFood("Chicken"), true);
    });
  });
}

우와! 😲 이 코드가 뭘 하는 건지 궁금하시죠? 차근차근 설명해드릴게요!

  1. 먼저 우리는 Cat이라는 클래스를 만들었어요. 이 고양이는 소리를 내고 음식을 먹을 수 있어요.
  2. 그 다음 MockCat이라는 가짜 고양이 클래스를 만들었어요. 이 가짜 고양이는 진짜 고양이처럼 행동할 거예요.
  3. 테스트에서는 이 가짜 고양이를 사용해서 소리를 내고 음식을 먹는 행동을 테스트해요.
  4. when(cat.sound()).thenReturn("Meow"); 이 부분은 "가짜 고양이야, 누군가 네 소리를 들으려고 하면 '야옹'이라고 해"라고 말하는 거예요.
  5. when(cat.eatFood(any)).thenReturn(true); 이 부분은 "가짜 고양이야, 누군가 너에게 어떤 음식을 주더라도 다 먹어"라고 말하는 거예요.

이렇게 Mockito를 사용하면 실제 객체 없이도 다양한 상황을 테스트할 수 있어요. 특히 네트워크 요청이나 데이터베이스 작업 같은 복잡한 동작을 테스트할 때 아주 유용하답니다!

여러분, 이해가 되셨나요? Mockito를 사용하면 마치 마법처럼 가짜 객체를 만들어낼 수 있어요. 이 가짜 객체들은 우리가 원하는 대로 행동하게 만들 수 있죠. 이렇게 하면 실제 환경에서 테스트하기 어려운 상황도 쉽게 테스트할 수 있답니다.

그런데 말이에요, Mockito를 사용할 때 주의해야 할 점이 있어요. 바로 너무 많은 것을 모킹하지 않는 것이에요. 모든 것을 모킹하면 실제 코드와 너무 동떨어진 테스트가 될 수 있거든요. 그러니까 꼭 필요한 부분만 모킹하고, 나머지는 실제 객체를 사용하는 게 좋아요.

자, 이제 Mockito의 기본을 알았으니 좀 더 복잡한 예제를 볼까요? 실제 앱 개발에서 자주 사용되는 HTTP 요청을 모킹하는 예제를 보여드릴게요!


import 'package:http/http.dart' as http;
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

class ApiClient {
  final http.Client client;

  ApiClient(this.client);

  Future<string> getData() async {
    final response = await client.get(Uri.parse('https://api.example.com/data'));
    if (response.statusCode == 200) {
      return response.body;
    } else {
      throw Exception('Failed to load data');
    }
  }
}

class MockClient extends Mock implements http.Client {}

void main() {
  group('ApiClient', () {
    test('returns data when http call completes successfully', () async {
      final client = MockClient();
      final apiClient = ApiClient(client);

      when(client.get(any))
          .thenAnswer((_) async => http.Response('{"data": "test"}', 200));

      expect(await apiClient.getData(), '{"data": "test"}');
    });

    test('throws an exception when http call completes with an error', () async {
      final client = MockClient();
      final apiClient = ApiClient(client);

      when(client.get(any))
          .thenAnswer((_) async => http.Response('Not Found', 404));

      expect(apiClient.getData(), throwsException);
    });
  });
}
</string>

우와! 😮 이 코드는 좀 더 복잡해 보이죠? 하지만 걱정 마세요. 천천히 설명해드릴게요!

  1. 먼저 ApiClient라는 클래스를 만들었어요. 이 클래스는 HTTP 요청을 보내고 데이터를 받아오는 역할을 해요.
  2. MockClient라는 가짜 HTTP 클라이언트를 만들었어요. 이 가짜 클라이언트를 사용해서 실제로 네트워크 요청을 보내지 않고도 테스트할 수 있어요.
  3. 첫 번째 테스트에서는 HTTP 요청이 성공적으로 완료되는 경우를 테스트해요. when(client.get(any)).thenAnswer((_) async => http.Response('{"data": "test"}', 200)); 이 부분이 "가짜 클라이언트야, 누군가 GET 요청을 보내면 이런 응답을 돌려줘"라고 말하는 거예요.
  4. 두 번째 테스트에서는 HTTP 요청이 실패하는 경우를 테스트해요. 이번에는 404 에러를 돌려주도록 설정했죠.

이렇게 Mockito를 사용하면 네트워크 요청같은 외부 의존성을 가진 코드도 쉽게 테스트할 수 있어요. 실제로 서버에 요청을 보내지 않아도 되니까 테스트가 빠르고 안정적이죠!

여러분, 이제 Mockito의 강력함이 느껴지시나요? 이렇게 Mockito를 사용하면 복잡한 상황도 쉽게 테스트할 수 있어요. 특히 Flutter 앱 개발에서 API 통신이나 데이터베이스 작업을 테스트할 때 정말 유용하답니다.

그런데 말이에요, Mockito를 사용할 때 한 가지 팁을 더 드릴게요. 바로 테스트 더블(Test Double)의 개념을 이해하는 거예요. 테스트 더블에는 여러 종류가 있는데, Mockito로는 주로 Mock과 Stub을 만들 수 있어요.

  • Stub: 미리 준비된 답변만 제공하는 객체예요. 주로 "이 메소드를 호출하면 이런 값을 반환해"라고 설정할 때 사용해요.
  • Mock: Stub보다 더 똑똑해요. 어떤 메소드가 호출되었는지, 몇 번 호출되었는지 등을 기억하고 검증할 수 있어요.

이 개념을 이해하고 있으면 Mockito를 더 효과적으로 사용할 수 있답니다!

자, 이제 Mockito에 대해 꽤 많이 알게 되셨죠? 다음으로 bloc_test에 대해 알아볼 차례예요. bloc_test는 Flutter의 상태 관리 라이브러리인 BLoC(Business Logic Component)를 테스트하는 데 특화된 라이브러리랍니다. 준비되셨나요? 그럼 고고! 🚀

3. bloc_test: BLoC 패턴의 완벽한 테스트 도구 🧪

여러분, BLoC 패턴 들어보셨나요? Flutter에서 상태 관리를 위해 많이 사용되는 패턴이에요. BLoC는 Business Logic Component의 약자로, 비즈니스 로직을 UI에서 분리하여 관리하는 방식이에요. 이렇게 하면 코드가 더 깔끔해지고 테스트하기 쉬워진답니다.

그런데 BLoC를 어떻게 테스트할까요? 여기서 바로 bloc_test 라이브러리가 등장합니다! bloc_test는 BLoC의 동작을 쉽게 테스트할 수 있게 해주는 강력한 도구예요.

🧪 bloc_test의 주요 기능:

1. BLoC의 상태 변화를 쉽게 테스트할 수 있어요.

2. 이벤트 발생에 따른 상태 변화를 검증할 수 있어요.

3. 비동기 동작도 쉽게 테스트할 수 있어요.

4. 에러 상황도 테스트할 수 있어요.

자, 이제 bloc_test를 사용해볼까요? 먼저 pubspec.yaml 파일에 bloc_test를 추가해야 해요.


dependencies:
  flutter:
    sdk: flutter
  bloc: ^8.0.0
  flutter_bloc: ^8.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  bloc_test: ^9.0.0
  mockito: ^5.0.0

이제 간단한 예제를 통해 bloc_test를 사용해볼게요. 카운터 앱을 만들어볼까요?


import 'package:bloc/bloc.dart';
import 'package:bloc_test/bloc_test.dart';
import 'package:test/test.dart';

// 이벤트 정의
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}

// BLoC 정의
class CounterBloc extends Bloc<counterevent int> {
  CounterBloc() : super(0) {
    on<incrementevent>((event, emit) => emit(state + 1));
    on<decrementevent>((event, emit) => emit(state - 1));
  }
}

void main() {
  group('CounterBloc', () {
    blocTest<counterbloc int>(
      'emits [1] when IncrementEvent is added',
      build: () => CounterBloc(),
      act: (bloc) => bloc.add(IncrementEvent()),
      expect: () => [1],
    );

    blocTest<counterbloc int>(
      'emits [-1] when DecrementEvent is added',
      build: () => CounterBloc(),
      act: (bloc) => bloc.add(DecrementEvent()),
      expect: () => [-1],
    );

    blocTest<counterbloc int>(
      'emits [1, 2, 1] when IncrementEvent, IncrementEvent, DecrementEvent are added',
      build: () => CounterBloc(),
      act: (bloc) => bloc
        ..add(IncrementEvent())
        ..add(IncrementEvent())
        ..add(DecrementEvent()),
      expect: () => [1, 2, 1],
    );
  });
}
</counterbloc></counterbloc></counterbloc></decrementevent></incrementevent></counterevent>

우와! 😲 이 코드가 뭘 하는 건지 궁금하시죠? 차근차근 설명해드릴게요!

  1. 먼저 우리는 CounterEvent라는 이벤트를 정의했어요. 증가(Increment)와 감소(Decrement) 두 가지 이벤트가 있죠.
  2. 그 다음 CounterBloc이라는 BLoC를 만들었어요. 이 BLoC는 카운터의 상태를 관리해요.
  3. 테스트에서는 blocTest라는 함수를 사용해요. 이 함수는 BLoC의 동작을 테스트하는 데 특화되어 있어요.
  4. 첫 번째 테스트에서는 증가 이벤트를 추가했을 때 상태가 1이 되는지 확인해요.
  5. 두 번째 테스트에서는 감소 이벤트를 추가했을 때 상태가 -1이 되는지 확인해요.
  6. 세 번째 테스트에서는 여러 이벤트를 연속해서 추가했을 때 상태가 어떻게 변하는지 확인해요.

이렇게 bloc_test를 사용하면 BLoC의 동작을 아주 세밀하게 테스트할 수 있어요. 특히 복잡한 상태 변화나 비동기 동작을 테스트할 때 정말 유용하답니다!

여러분, 이해가 되셨나요? bloc_test를 사용하면 마치 마법처럼 BLoC의 동작을 검증할 수 있어요. 이렇게 하면 앱의 상태 관리 로직이 제대로 동작하는지 쉽게 확인할 수 있답니다.

그런데 말이에요, bloc_test를 사용할 때 주의해야 할 점이 있어요. 바로 테스트가 너무 구체적이지 않도록 하는 것이에요. 너무 세세한 부분까지 테스트하면 코드가 조금만 바뀌어도 테스트가 깨질 수 있거든요. 그러니까 중요한 동작 위주로 테스트를 작성하는 게 좋아요.

자, 이제 bloc_test의 기본을 알았으니 좀 더 복잡한 예제를 볼까요? 실제 앱 개발에서 자주 사용되는 비동기 동작을 테스트하는 예제를 보여드릴게요!


import 'package:bloc/bloc.dart';
import 'package:bloc_test/bloc_test.dart';
import 'package:test/test.dart';

// 이벤트 정의
abstract class WeatherEvent {}
class FetchWeather extends WeatherEvent {
  final String city;
  FetchWeather(this.city);
}

// 상태 정의
abstract class WeatherState {}
class WeatherInitial extends WeatherState {}
class WeatherLoading extends WeatherState {}
class WeatherLoaded extends WeatherState {
  final String weather;
  WeatherLoaded(this.weather);
}
class WeatherError extends WeatherState {
  final String message;
  WeatherError(this.message);
}

// 날씨 서비스 (실제로는 API 호출을 하겠지만, 여기서는 간단히 구현)
class WeatherService {
  Future<string> getWeather(String city) async {
    await Future.delayed(Duration(seconds: 1)); // API 호출을 시뮬레이션
    if (city == 'Error') throw Exception('Failed to fetch weather');
    return 'Sunny';
  }
}

// BLoC 정의
class WeatherBloc extends Bloc<weatherevent weatherstate> {
  final WeatherService weatherService;

  WeatherBloc(this.weatherService) : super(WeatherInitial()) {
    on<fetchweather>((event, emit) async {
      emit(WeatherLoading());
      try {
        final weather = await weatherService.getWeather(event.city);
        emit(WeatherLoaded(weather));
      } catch (e) {
        emit(WeatherError('Failed to fetch weather'));
      }
    });
  }
}

void main() {
  group('WeatherBloc', () {
    late WeatherService weatherService;

    setUp(() {
      weatherService = WeatherService();
    });

    blocTest<weatherbloc weatherstate>(
      'emits [WeatherLoading, WeatherLoaded] when FetchWeather is added',
      build: () => WeatherBloc(weatherService),
      act: (bloc) => bloc.add(FetchWeather('Seoul')),
      expect: () => [
        WeatherLoading(),
        WeatherLoaded('Sunny'),
      ],
    );

    blocTest<weatherbloc weatherstate>(
      'emits [WeatherLoading, WeatherError] when FetchWeather fails',
      build: () => WeatherBloc(weatherService),
      act: (bloc) => bloc.add(FetchWeather('Error')),
      expect: () => [
        WeatherLoading(),
        WeatherError('Failed to fetch weather'),
      ],
    );
  });
}
</weatherbloc></weatherbloc></fetchweather></weatherevent></string>

우와! 😮 이 코드는 좀 더 복잡해 보이죠? 하지만 걱정 마세요. 천천히 설명해드릴게요!

  1. 먼저 WeatherEventWeatherState를 정의했어요. 이벤트는 날씨 정보를 가져오는 동작을 나타내고, 상태는 초기, 로딩 중, 로딩 완료, 에러 상태를 나타내요.
  2. WeatherService라는 가상의 서비스를 만들었어요. 실제로는 API 호출을 하겠지만, 여기서는 간단히 구현했어요.
  3. WeatherBloc은 이벤트를 받아서 상태를 변경해요. 날씨 정보를 가져오는 동안 로딩 상태가 되고, 성공하면 날씨 정보를, 실패하면 에러 상태를 emit해요.
  4. 첫 번째 테스트에서는 날씨 정보를 성공적으로 가져오는 경우를 테스트해요. [WeatherLoading, WeatherLoaded] 순서로 상태가 변하는지 확인하죠.
  5. 두 번째 테스트에서는 날씨 정보를 가져오는 데 실패하는 경우를 테스트해요. [WeatherLoading, WeatherError] 순서로 상태가 변하는지 확인하죠.

이렇게 bloc_test를 사용하면 비동기 동작을 포함한 복잡한 BLoC의 동작도 쉽게 테스트할 수 있어요. 실제 앱에서는 API 호출이나 데이터베이스 작업 같은 비동기 동작이 많이 일어나는데, 이런 상황을 테스트하기 perfect하답니다!

여러분, 이제 bloc_test의 강력함 이 느껴지시나요? 이렇게 bloc_test를 사용하면 복잡한 상태 관리 로직도 쉽게 테스트할 수 있어요. 특히 Flutter 앱 개발에서 BLoC 패턴을 사용할 때 정말 유용하답니다.

그런데 말이에요, bloc_test를 사용할 때 한 가지 팁을 더 드릴게요. 바로 시간에 따른 상태 변화를 테스트하는 방법이에요. bloc_test는 시간에 따른 상태 변화도 테스트할 수 있는 기능을 제공해요. 이를 위해 'wait' 매개변수를 사용할 수 있답니다.

예를 들어볼까요?


blocTest<weatherbloc weatherstate>(
  'emits [WeatherLoading, WeatherLoaded] with 1 second delay',
  build: () => WeatherBloc(weatherService),
  act: (bloc) => bloc.add(FetchWeather('Seoul')),
  wait: const Duration(seconds: 1),
  expect: () => [
    WeatherLoading(),
    WeatherLoaded('Sunny'),
  ],
);
</weatherbloc>

이 테스트는 WeatherLoading 상태가 즉시 emit되고, 1초 후에 WeatherLoaded 상태가 emit되는 것을 확인해요. 이렇게 하면 시간에 따른 상태 변화도 정확하게 테스트할 수 있답니다!

자, 이제 Mockito와 bloc_test에 대해 꽤 많이 알게 되셨죠? 이 두 도구를 잘 활용하면 Flutter 앱의 품질을 크게 높일 수 있어요. 테스트를 작성하는 것이 처음에는 시간이 좀 걸리겠지만, 장기적으로 보면 버그를 줄이고 개발 속도를 높이는 데 큰 도움이 된답니다.

그런데 여기서 끝이 아니에요! 테스트 자동화의 세계는 정말 넓고 깊답니다. 여러분이 이 글을 읽고 테스트에 관심을 가지게 되셨다면, 다음 주제들도 한번 살펴보시는 것을 추천해요:

  • 통합 테스트 (Integration Tests): 여러 컴포넌트가 함께 동작하는 것을 테스트해요.
  • 골든 테스트 (Golden Tests): UI의 시각적 일관성을 테스트해요.
  • 성능 테스트 (Performance Tests): 앱의 성능을 측정하고 개선할 수 있어요.
  • TDD (Test-Driven Development): 테스트를 먼저 작성하고 그 다음에 코드를 작성하는 개발 방법론이에요.

테스트는 개발자의 필수 스킬이에요. 여러분도 이제 Mockito와 bloc_test를 사용해서 멋진 테스트 코드를 작성해보세요! 💪

마지막으로, 테스트를 작성할 때 기억해야 할 중요한 점이 있어요. 바로 테스트는 문서의 역할도 한다는 거예요. 잘 작성된 테스트 코드는 그 자체로 코드의 동작을 설명하는 훌륭한 문서가 될 수 있답니다. 그러니 테스트를 작성할 때는 다른 개발자들도 쉽게 이해할 수 있도록 명확하고 의미 있는 이름을 사용하고, 필요하다면 주석도 달아주세요.

자, 이제 정말 끝이에요! 여러분은 이제 Flutter 테스트 자동화의 달인이 되셨어요. Mockito와 bloc_test를 활용해서 여러분의 앱을 더욱 견고하고 안정적으로 만들어보세요. 화이팅! 🚀

관련 키워드

  • Flutter
  • 테스트 자동화
  • Mockito
  • bloc_test
  • 단위 테스트
  • 위젯 테스트
  • BLoC 패턴
  • 상태 관리
  • 비동기 테스트
  • TDD

지적 재산권 보호

지적 재산권 보호 고지

  1. 저작권 및 소유권: 본 컨텐츠는 재능넷의 독점 AI 기술로 생성되었으며, 대한민국 저작권법 및 국제 저작권 협약에 의해 보호됩니다.
  2. AI 생성 컨텐츠의 법적 지위: 본 AI 생성 컨텐츠는 재능넷의 지적 창작물로 인정되며, 관련 법규에 따라 저작권 보호를 받습니다.
  3. 사용 제한: 재능넷의 명시적 서면 동의 없이 본 컨텐츠를 복제, 수정, 배포, 또는 상업적으로 활용하는 행위는 엄격히 금지됩니다.
  4. 데이터 수집 금지: 본 컨텐츠에 대한 무단 스크래핑, 크롤링, 및 자동화된 데이터 수집은 법적 제재의 대상이 됩니다.
  5. AI 학습 제한: 재능넷의 AI 생성 컨텐츠를 타 AI 모델 학습에 무단 사용하는 행위는 금지되며, 이는 지적 재산권 침해로 간주됩니다.

재능넷은 최신 AI 기술과 법률에 기반하여 자사의 지적 재산권을 적극적으로 보호하며,
무단 사용 및 침해 행위에 대해 법적 대응을 할 권리를 보유합니다.

© 2024 재능넷 | All rights reserved.

댓글 작성
0/2000

댓글 0개

해당 지식과 관련있는 인기재능

애플리케이션 서비스 안녕하세요. 안드로이드 개발자입니다.여러분들의 홈페이지,블로그,카페,모바일 등 손쉽게 어플로 제작 해드립니다.요즘...

 안녕하세요 현재 안드로이드 기반 어플리케이션 제작 및 서비스를 하고 있으며,스타트업회사에 재직중입니다.- 개인앱, 프로젝트용 앱 등부...

📚 생성된 총 지식 10,492 개

  • (주)재능넷 | 대표 : 강정수 | 경기도 수원시 영통구 봉영로 1612, 7층 710-09 호 (영통동) | 사업자등록번호 : 131-86-65451
    통신판매업신고 : 2018-수원영통-0307 | 직업정보제공사업 신고번호 : 중부청 2013-4호 | jaenung@jaenung.net

    (주)재능넷의 사전 서면 동의 없이 재능넷사이트의 일체의 정보, 콘텐츠 및 UI등을 상업적 목적으로 전재, 전송, 스크래핑 등 무단 사용할 수 없습니다.
    (주)재능넷은 통신판매중개자로서 재능넷의 거래당사자가 아니며, 판매자가 등록한 상품정보 및 거래에 대해 재능넷은 일체 책임을 지지 않습니다.

    Copyright © 2024 재능넷 Inc. All rights reserved.
ICT Innovation 대상
미래창조과학부장관 표창
서울특별시
공유기업 지정
한국데이터베이스진흥원
콘텐츠 제공서비스 품질인증
대한민국 중소 중견기업
혁신대상 중소기업청장상
인터넷에코어워드
일자리창출 분야 대상
웹어워드코리아
인터넷 서비스분야 우수상
정보통신산업진흥원장
정부유공 표창장
미래창조과학부
ICT지원사업 선정
기술혁신
벤처기업 확인
기술개발
기업부설 연구소 인정
마이크로소프트
BizsPark 스타트업
대한민국 미래경영대상
재능마켓 부문 수상
대한민국 중소기업인 대회
중소기업중앙회장 표창
국회 중소벤처기업위원회
위원장 표창