SlideShare a Scribd company logo
1 of 71
Download to read offline
嵌入式測試驅動開發
Hugo
2/13/2014
熟悉的開發方式
先寫程式,再寫測試

bug

Test-After Development (TAD)
問題是...
沒出錯不知道哪裡有 bug
bug 小時候放著不管
長大很恐怖
有什麼方法...
能盡早把 bug 出來?
先寫測試

bug,再寫程式

Test-Driven Development (TDD)
Test
Driven
Development
測試驅動開發
TDD 循環
加 紅燈:增 一個運行失敗,
甚至無法 譯的測試
加 綠燈:快 修改, 做能讓
測試 過的工作
加 黃燈:重構,移除重複改進
代碼可讀性

Test Driven Development: By Example
測試 是 TDD 的關鍵
建立

運行

驗證

拆卸

Setup

Exercise

Verify

Teardown

單元測試四階段
自動化單元測試框架
測試案例 #1

測試案例#2

...

report

測試結果 #1

測試框架
產品代碼 ( 測代碼)

proj/

測試結果 #2
...

fun.c

objs/
projTest/

src/

func.o

src/

funTest.c

objs/

func.o
funcTest.o

目標環境

測試環境
TDD 的好處
加
加
加
加
加
加

產生 bug 更少
除錯時間更短
不會說謊的文件
改善設計
監督進度
心平靜
嵌入式測試驅動開發
有什麼特別的地方嗎?
依賴硬體,浪費時間
Code

單元測試

運行系統

開發環境

目標環境

雙目標開發 - 解開硬體的依賴
嵌入式 TDD 循環
階段一

階段二

階段三

階段四

階段五

開發環境
TDD

交叉 譯
相容測試

評估版
單元測試

目標硬體
單元測試

目標硬體
驗收測試

很頻繁

不頻繁

Test-Driven Development for Embedded C
嵌入式驅動開發工具
加 Unity
– C 語言自動化測試框架
– 用 Ruby Script 安裝測試

加 CppUTest
– C/C++自動化測試框架
– 用 Ruby Script 測試轉
換 Unity 測試

Unity http://throwtheswitch.org/, CppUTest http://cpputest.github.io/
範例 - 開發 LED 驅動程式
玩意

10行程式就搞定了
麼簡單還需要測試嗎?
MyLedDriver.c
#define LED_REGISTER 0x80001234
void LedDriver_Set (uint16_t value)
{
*((uint16_t *)LED_REGISTER) = value;
}
uint16_t LedDriver_Get (void)
{
return *((uint16_t *)LED_REGISTER);
}
LedUser.c

void TurnOnLed8 (void)
{
LedDriver_Set (1 << 8);
}
沒有測試把關
再怎麼簡單都可能出錯
TDD 會怎麼做?
測試列表
先寫出測試失敗的測試
LedDriverTest.c
TEST (LedDriver, LedsOffAfterCreate)
{
uint16_t virtualLeds = 0xffff;
LedDriver_Create (&virtualLeds);
TEST_ASSERT_EQUAL (0, virtualLeds);
}

LedDriver.c
void LedDriver_Create (uint16_t* address)
{
}
Dependence Injection (依賴注入)
用最簡單的方式讓測試 過
LedDriver.c
void LedDriver_Create (uint16_t* address)
{
*address = 0;
}

$ make
compiling LedDriver.c
Linking LedDirver_tests
Running LedDriver_tests
.
OK (1 tests, 1 ran, 1 checks, 0 ignored)
再增

一個測試

LedDriverTest.c
TEST (LedDriver, TurnOnLedOne)
{
uint16_t virtualLeds;
LedDriver_Create (&virtualLeds);
LedDriver_TurnOn (1);
TEST_ASSERT_EQUAL (1, virtualLeds);
}

LedDriver.c
void LedDriver_TurnOn (int ledNumber)
{
}
寫 hardcode 讓測試 過
LedDriver.c
static uint16_t* ledsAddress;
void LedDriver_Create (uint16_t* address)
{
ledsAddress = address;
*ledsAddress = 0;
}
void LedDriver_TurnOn (int ledNumber)
{
*ledDriver = 1;
}

Data Encapsulation (資料封裝)
等等! 不科學啊...
hardcode 的實作有問題
增 非當下測試所需的代碼
會降低捕捉各種 bug 的動力
先仿冒再建
保持小而 注的測試
TDD 像是過河的墊腳石
喔...

就是 TDD 嗎?
真正的系統長的像

樣
依賴像一串肉粽
控制輸入 & 監測輸出

直接輸入

直接輸出

間接輸出

間接輸入
斷開魂結

斷開鎖鍊
測試 替身
何時使用測試替身?
加
加
加
加
加
加

獨立於硬體
注入 以產生的輸入
慢的合作者
依賴不穩定的事情
代未被實現的服務
對於 以配置的事物的依賴
測試替身的替換

術

加 譯時期,透過 Preprocessor 替換
加 連結時期,透過 Object File 替換
加 執行時期,透過 Function Pointer 替換
Test Stub

xUnit Test Patterns: Refactoring Test Code
FakeTimeService.c
static int theMinute;
void FakeTimeService_SetMinute (int minute)
{
theMinute = minute;
}
void TimeService_GetTime (Time* time)
{
time->minuteOfDay = theMinute;
}
FakeTimeServiceTest.c
TEST (FakeTimeService, Set)
{
Time time;

FakeTimeService_SetMinute (42);
TimeService_GetTime (&time);
LONGS_EQUAL (42, time.minuteOfDay);
}
Test Spy
FakeTimeService.c
static int theMinute;
int FakeTimeService_GetMinute (void)
{
return theMinute;
}
void TimeService_SetDay (Time* time)
{
theMinute = time->minuteOfDay;
}
FakeTimeServiceTest.c
TEST (FakeTimeService, Get)
{
Time time;

time->minuteOfDay = 42;
TimeService_SetTime (&time);
LONGS_EQUAL (42, FakeTimeService_GetMinute());
}
Mock Object
Flash Program 序列圖 -

的情形
FlashTest.c
TEST (Flash, WriteSucceeds)
{
int result = 0;
MockIO_Expect_Write (0, 0x40);
MockIO_Expect_Write (0x1000, 0xBEEF);
MockIO_Expect_ReadThenReturn (0, 1<<7);
MockIo_Expect_ReadThenReturn (0, 1<<7);
MockIO_Expect_ReadThenReturn (0x1000, 0xBEEF);
Result = Flash_Write (0x1000, 0xBEEF);
LONG_EQUAL (0, result);
MockIO_Verify_Complete();

}

CMock http://throwtheswitch.org/, CppUMock http://cpputest.github.io/
怎樣才算好設計?
可測性 可讀性 可維護性
借用物件導向的設計原則
用 C 語言實現資料封裝
WallClock.h
void WallClock_SetTime (Time time);
Time WallClock_GetTime (void);

Watch.h
typedef struct WatchStruct Watch;
void SetTime (Watch* watch, Time time);
Time GetTime (Watch* watch);
用 C 語言實現類別繼
Watch.h
typedef struct WatchStruct {
void (*SetTime) (Watch*, Time);
Time (*GetTime) (Watch*);
} Watch;

interface
Watch

DigitalWatch.c

typedef struct DigitalWatchStruct {
Watch* base;
Time time;
} DigitalWatch;
Watch* DigitalWatch_Create (void) {
DigitalWatch* self = malloc(sizeof(DigitalWatch));
self->base->SetTime = mySetTime;
self->base->GetTime = myGetTime;
return (Watch*)self;
}

Digital
Watch
用 C 語言實現類別多型
User.c
void doSetTime (Watch* watch, Time time) {
watch->SetTime (watch, time);
}

User

interface
Watch

DigitalWatch.c
static void mySetTime (Watch* watch, Time time)
{
DigitalWatch* self = (DigitalWatch*)watch;
self->time = time;
}
MechanicWatch.c
static void mySetTime (Watch* watch, Time time)
{
MechanicWatch* self = (MechanicWatch*)watch;
self->time = time;
}

Digital
Watch

Mechanic
Watch
SOLID 設計原則
User

interface
Watch

Digital
Watch

Mechanic
Watch

Pocket
Watch

SRP 單一職責
OCP 開放封閉
LSP 替換原則
ISP 介面分
DIP 依賴 轉

Agile Software Development, Principle, Patterns, and Practices
隨著代碼不斷增
系統架構變得越來越混亂
代碼的壞味道
加
加
加
加
加
加
加
加
加
加
加

重複代碼
壞名字
義大利麵式代碼
長函式
眼花撩亂的布林運算
重複的 switch/case
邪惡的嵌套
依戀情結
參數太多
注釋 注釋掉的代碼
條件 譯
CodeSmells.c
void foobar (Time* time, Work* work)
{
if (work->item != NULL) {
Day day = time->dayOfWeek;
int min = time->minuteOfDay;
if ((day >= MONDAY && day <= FRIDAY) &&
((min >= 9*60 && min <= 12*60) ||
(min >= 13*60 && min <= 18*60)) {
if (work->type == CODING)
doCode (work->item);
else
doDebug (work->item);
// doSomethingImportant ();
}
}
}
重構是
在不改變當前外部行為的條件下,
對現有代碼進行修改的過程

Refactoring: Improving the Design of Existing Code
RefactoredCode.c
static bool isWorkTime (Time* time)
{
...
}
static void workHard (Work* work)
{
...
}
void workInOffice (Time* time, Work* work)
{
if (!isWorkTime(time))
return;
workHard (work);

}
唉呦 不錯 重構

個屌
但實際動手
你肯定會講一句話...
砍掉重練比較快
在真實世界裡
必須要跟遺留代碼戰鬥
遺留代碼 = 沒有測試的代碼
修改遺留代碼
•
•
•
•
•

發現改動點
到測試點
斷開依賴
寫測試
改動和重構

Working Efficiently with Legacy Code
測試點
加 接縫 (函式呼 )
加 域變數/感知變量
加 除錯輸出
加 嵌入監控
把遺留代碼放到測試框架中
TestLegacyCode.c
void addNewLegacyCTest()
{
makeItCompile();
makeItLink();
while (runCrashes()) {
findRuntimeDependency();
fixRuntimeDependency();
}
addMoreLegacyCTests();
}
TDD 聽來不錯,但是...
不知怎麼開始?
先來場 Coding Dojo 吧
參考資料
Test-Driven Development for Embedded C
Test Driven Development: By Example
xUnit Test Patterns: Refactoring Test Code
Refactoring: Improving the Design of Existing Code
Working Efficiently with Legacy Code
Agile Software Development, Principle, Patterns, and Practices
Design Patterns for Embedded Systems in C: An Embedded
Software Engineering Toolkit

More Related Content

What's hot

Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
Theo Jungeblut
 
NDC14 - 사례로 배우는 디스어셈블리 디버깅
NDC14 - 사례로 배우는 디스어셈블리 디버깅NDC14 - 사례로 배우는 디스어셈블리 디버깅
NDC14 - 사례로 배우는 디스어셈블리 디버깅
Seungjae Lee
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
Dhaval Dalal
 
2014/02: 嵌入式測試驅動開發
2014/02: 嵌入式測試驅動開發2014/02: 嵌入式測試驅動開發
2014/02: 嵌入式測試驅動開發
AgileCommunity
 

What's hot (20)

A quick and fast intro to Kotlin
A quick and fast intro to Kotlin A quick and fast intro to Kotlin
A quick and fast intro to Kotlin
 
The Art of Unit Testing - Towards a Testable Design
The Art of Unit Testing - Towards a Testable DesignThe Art of Unit Testing - Towards a Testable Design
The Art of Unit Testing - Towards a Testable Design
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
 
Introducing Clean Architecture
Introducing Clean ArchitectureIntroducing Clean Architecture
Introducing Clean Architecture
 
Introduction to kotlin
Introduction to kotlinIntroduction to kotlin
Introduction to kotlin
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
 
Unit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdfUnit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdf
 
NDC14 - 사례로 배우는 디스어셈블리 디버깅
NDC14 - 사례로 배우는 디스어셈블리 디버깅NDC14 - 사례로 배우는 디스어셈블리 디버깅
NDC14 - 사례로 배우는 디스어셈블리 디버깅
 
Java Unit Testing
Java Unit TestingJava Unit Testing
Java Unit Testing
 
Clean code
Clean codeClean code
Clean code
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golang
 
TDD (Test-driven development, 測試驅動開發) 基本教學
TDD (Test-driven development, 測試驅動開發) 基本教學TDD (Test-driven development, 測試驅動開發) 基本教學
TDD (Test-driven development, 測試驅動開發) 基本教學
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
JUnit Presentation
JUnit PresentationJUnit Presentation
JUnit Presentation
 
Unit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of PurityUnit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of Purity
 
Clean code slide
Clean code slideClean code slide
Clean code slide
 
Borland C++Builder 進階課程
Borland C++Builder 進階課程Borland C++Builder 進階課程
Borland C++Builder 進階課程
 
2014/02: 嵌入式測試驅動開發
2014/02: 嵌入式測試驅動開發2014/02: 嵌入式測試驅動開發
2014/02: 嵌入式測試驅動開發
 

Viewers also liked

初探行为驱动开发(Bdd)
初探行为驱动开发(Bdd)初探行为驱动开发(Bdd)
初探行为驱动开发(Bdd)
YuLei Liao
 
Test driven development in C
Test driven development in CTest driven development in C
Test driven development in C
Amritayan Nayak
 

Viewers also liked (6)

關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......
 
Test-Driven Development for Embedded C -- OOP Conference 2015, Munich
Test-Driven Development for Embedded C -- OOP Conference 2015, MunichTest-Driven Development for Embedded C -- OOP Conference 2015, Munich
Test-Driven Development for Embedded C -- OOP Conference 2015, Munich
 
Coding dojo初體驗
Coding dojo初體驗Coding dojo初體驗
Coding dojo初體驗
 
初探行为驱动开发(Bdd)
初探行为驱动开发(Bdd)初探行为驱动开发(Bdd)
初探行为驱动开发(Bdd)
 
認試軟體測試的世界 & TDD/BDD 入門
認試軟體測試的世界 & TDD/BDD 入門認試軟體測試的世界 & TDD/BDD 入門
認試軟體測試的世界 & TDD/BDD 入門
 
Test driven development in C
Test driven development in CTest driven development in C
Test driven development in C
 

Similar to 嵌入式測試驅動開發

Foundation of software development 1
Foundation of software development 1Foundation of software development 1
Foundation of software development 1
netdbncku
 
Clojure cnclojure-meetup
Clojure cnclojure-meetupClojure cnclojure-meetup
Clojure cnclojure-meetup
sunng87
 
GTest交流与经验总结
GTest交流与经验总结GTest交流与经验总结
GTest交流与经验总结
coderzh
 
2006 recycle opensourceprojects
2006 recycle opensourceprojects2006 recycle opensourceprojects
2006 recycle opensourceprojects
George Ang
 
Recycle Open Source Projects
Recycle Open Source ProjectsRecycle Open Source Projects
Recycle Open Source Projects
George Ang
 
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Gelis Wu
 
2006年招聘试题
2006年招聘试题2006年招聘试题
2006年招聘试题
yiditushe
 

Similar to 嵌入式測試驅動開發 (20)

Android 智慧型手機程式設計
Android 智慧型手機程式設計Android 智慧型手機程式設計
Android 智慧型手機程式設計
 
如何在實務上使用TDD來開發 twmvc#12
如何在實務上使用TDD來開發 twmvc#12如何在實務上使用TDD來開發 twmvc#12
如何在實務上使用TDD來開發 twmvc#12
 
twMVC#12 | 如何在實務上使用 TDD 來開發
twMVC#12 | 如何在實務上使用 TDD 來開發twMVC#12 | 如何在實務上使用 TDD 來開發
twMVC#12 | 如何在實務上使用 TDD 來開發
 
Foundation of software development 1
Foundation of software development 1Foundation of software development 1
Foundation of software development 1
 
第1章概述
第1章概述第1章概述
第1章概述
 
Clojure cnclojure-meetup
Clojure cnclojure-meetupClojure cnclojure-meetup
Clojure cnclojure-meetup
 
GTest交流与经验总结
GTest交流与经验总结GTest交流与经验总结
GTest交流与经验总结
 
Programming in Objective-C
Programming in Objective-CProgramming in Objective-C
Programming in Objective-C
 
2006 recycle opensourceprojects
2006 recycle opensourceprojects2006 recycle opensourceprojects
2006 recycle opensourceprojects
 
Recycle Open Source Projects
Recycle Open Source ProjectsRecycle Open Source Projects
Recycle Open Source Projects
 
用 Drone 打造 輕量級容器持續交付平台
用 Drone 打造輕量級容器持續交付平台用 Drone 打造輕量級容器持續交付平台
用 Drone 打造 輕量級容器持續交付平台
 
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
 
在B2B硬體產業運用 Agile 與 DevOps 的實務與心法
在B2B硬體產業運用 Agile 與 DevOps 的實務與心法在B2B硬體產業運用 Agile 與 DevOps 的實務與心法
在B2B硬體產業運用 Agile 與 DevOps 的實務與心法
 
漫談 Source Control Management
漫談 Source Control Management漫談 Source Control Management
漫談 Source Control Management
 
一個微信專案從0到000的效能調教
一個微信專案從0到000的效能調教一個微信專案從0到000的效能調教
一個微信專案從0到000的效能調教
 
面向模式的软件体系架构
面向模式的软件体系架构面向模式的软件体系架构
面向模式的软件体系架构
 
從理想、到現實的距離,開啟品味軟體測試之路 - 台灣軟體工程協會 (20220813)
從理想、到現實的距離,開啟品味軟體測試之路 - 台灣軟體工程協會 (20220813)從理想、到現實的距離,開啟品味軟體測試之路 - 台灣軟體工程協會 (20220813)
從理想、到現實的距離,開啟品味軟體測試之路 - 台灣軟體工程協會 (20220813)
 
使用 Pytest 進行單元測試 (PyCon TW 2021)
使用 Pytest 進行單元測試 (PyCon TW 2021)使用 Pytest 進行單元測試 (PyCon TW 2021)
使用 Pytest 進行單元測試 (PyCon TW 2021)
 
2006年招聘试题
2006年招聘试题2006年招聘试题
2006年招聘试题
 
[DevOpsDays] 硬體產業的DevOps導入與實踐 - 以工控產業為例
[DevOpsDays] 硬體產業的DevOps導入與實踐 - 以工控產業為例[DevOpsDays] 硬體產業的DevOps導入與實踐 - 以工控產業為例
[DevOpsDays] 硬體產業的DevOps導入與實踐 - 以工控產業為例
 

More from hugo lu

Testing in swift
Testing in swiftTesting in swift
Testing in swift
hugo lu
 
The linux networking architecture
The linux networking architectureThe linux networking architecture
The linux networking architecture
hugo lu
 

More from hugo lu (12)

WSO2 IoTS Device Manufacturer Guide
WSO2 IoTS Device Manufacturer GuideWSO2 IoTS Device Manufacturer Guide
WSO2 IoTS Device Manufacturer Guide
 
Dev ops 簡介
Dev ops 簡介Dev ops 簡介
Dev ops 簡介
 
Sql injection 幼幼班
Sql injection 幼幼班Sql injection 幼幼班
Sql injection 幼幼班
 
Sql or no sql, that is the question
Sql or no sql, that is the questionSql or no sql, that is the question
Sql or no sql, that is the question
 
Continuous integration
Continuous integrationContinuous integration
Continuous integration
 
Swift 2.0 的新玩意
Swift 2.0 的新玩意Swift 2.0 的新玩意
Swift 2.0 的新玩意
 
精實執行工作坊
精實執行工作坊精實執行工作坊
精實執行工作坊
 
Testing in swift
Testing in swiftTesting in swift
Testing in swift
 
畫出商業模式
畫出商業模式畫出商業模式
畫出商業模式
 
The linux networking architecture
The linux networking architectureThe linux networking architecture
The linux networking architecture
 
精實軟體度量
精實軟體度量精實軟體度量
精實軟體度量
 
看板實驗室
看板實驗室看板實驗室
看板實驗室
 

Recently uploaded

真的可以找黑客修改塔斯马尼亚大学 University of Tasmania改成绩黑客竟然可以找到漏洞来修改大学成绩,这真的让我感到非常惊讶和佩服。【...
真的可以找黑客修改塔斯马尼亚大学  University of Tasmania改成绩黑客竟然可以找到漏洞来修改大学成绩,这真的让我感到非常惊讶和佩服。【...真的可以找黑客修改塔斯马尼亚大学  University of Tasmania改成绩黑客竟然可以找到漏洞来修改大学成绩,这真的让我感到非常惊讶和佩服。【...
真的可以找黑客修改塔斯马尼亚大学 University of Tasmania改成绩黑客竟然可以找到漏洞来修改大学成绩,这真的让我感到非常惊讶和佩服。【...
微信 tytyqqww业务接单
 
真实可查(utk毕业证)田纳西大学毕业证田纳西大学本科学位文凭学历认证原版一模一样
真实可查(utk毕业证)田纳西大学毕业证田纳西大学本科学位文凭学历认证原版一模一样真实可查(utk毕业证)田纳西大学毕业证田纳西大学本科学位文凭学历认证原版一模一样
真实可查(utk毕业证)田纳西大学毕业证田纳西大学本科学位文凭学历认证原版一模一样
yuhpu
 
如何制作一个日本LCA大学院大学学位记🌈合格通知书电子版制作🌈补办爱尔兰大学文凭🌈LCCI证书定制
如何制作一个日本LCA大学院大学学位记🌈合格通知书电子版制作🌈补办爱尔兰大学文凭🌈LCCI证书定制如何制作一个日本LCA大学院大学学位记🌈合格通知书电子版制作🌈补办爱尔兰大学文凭🌈LCCI证书定制
如何制作一个日本LCA大学院大学学位记🌈合格通知书电子版制作🌈补办爱尔兰大学文凭🌈LCCI证书定制
tannergood250
 
永久可查英国北安普顿大学毕业证(uom学位证书)电子版学位证书留服认证原版一模一样
永久可查英国北安普顿大学毕业证(uom学位证书)电子版学位证书留服认证原版一模一样永久可查英国北安普顿大学毕业证(uom学位证书)电子版学位证书留服认证原版一模一样
永久可查英国北安普顿大学毕业证(uom学位证书)电子版学位证书留服认证原版一模一样
yuhpu
 
【微 tytyqqww 信】网上找黑客改蒙纳士大学__Monash University修改成绩黑客修改成绩,黑客改高考成绩,黑客修改中考成绩1.🎉你是否...
【微 tytyqqww 信】网上找黑客改蒙纳士大学__Monash University修改成绩黑客修改成绩,黑客改高考成绩,黑客修改中考成绩1.🎉你是否...【微 tytyqqww 信】网上找黑客改蒙纳士大学__Monash University修改成绩黑客修改成绩,黑客改高考成绩,黑客修改中考成绩1.🎉你是否...
【微 tytyqqww 信】网上找黑客改蒙纳士大学__Monash University修改成绩黑客修改成绩,黑客改高考成绩,黑客修改中考成绩1.🎉你是否...
微信 tytyqqww业务接单
 

Recently uploaded (7)

成绩修改,黑客入侵,黑客修改成绩,大学成绩能改吗改GPA,大学改分数哇塞,听说有人改大学毕业成绩了?😲 黑客大大太牛了吧!这就是传说中的学霸操作吗?佩服佩...
成绩修改,黑客入侵,黑客修改成绩,大学成绩能改吗改GPA,大学改分数哇塞,听说有人改大学毕业成绩了?😲 黑客大大太牛了吧!这就是传说中的学霸操作吗?佩服佩...成绩修改,黑客入侵,黑客修改成绩,大学成绩能改吗改GPA,大学改分数哇塞,听说有人改大学毕业成绩了?😲 黑客大大太牛了吧!这就是传说中的学霸操作吗?佩服佩...
成绩修改,黑客入侵,黑客修改成绩,大学成绩能改吗改GPA,大学改分数哇塞,听说有人改大学毕业成绩了?😲 黑客大大太牛了吧!这就是传说中的学霸操作吗?佩服佩...
 
真的可以找黑客修改塔斯马尼亚大学 University of Tasmania改成绩黑客竟然可以找到漏洞来修改大学成绩,这真的让我感到非常惊讶和佩服。【...
真的可以找黑客修改塔斯马尼亚大学  University of Tasmania改成绩黑客竟然可以找到漏洞来修改大学成绩,这真的让我感到非常惊讶和佩服。【...真的可以找黑客修改塔斯马尼亚大学  University of Tasmania改成绩黑客竟然可以找到漏洞来修改大学成绩,这真的让我感到非常惊讶和佩服。【...
真的可以找黑客修改塔斯马尼亚大学 University of Tasmania改成绩黑客竟然可以找到漏洞来修改大学成绩,这真的让我感到非常惊讶和佩服。【...
 
塔木德智慧全书:传承千年的犹太人智慧圣经_--------------------
塔木德智慧全书:传承千年的犹太人智慧圣经_--------------------塔木德智慧全书:传承千年的犹太人智慧圣经_--------------------
塔木德智慧全书:传承千年的犹太人智慧圣经_--------------------
 
真实可查(utk毕业证)田纳西大学毕业证田纳西大学本科学位文凭学历认证原版一模一样
真实可查(utk毕业证)田纳西大学毕业证田纳西大学本科学位文凭学历认证原版一模一样真实可查(utk毕业证)田纳西大学毕业证田纳西大学本科学位文凭学历认证原版一模一样
真实可查(utk毕业证)田纳西大学毕业证田纳西大学本科学位文凭学历认证原版一模一样
 
如何制作一个日本LCA大学院大学学位记🌈合格通知书电子版制作🌈补办爱尔兰大学文凭🌈LCCI证书定制
如何制作一个日本LCA大学院大学学位记🌈合格通知书电子版制作🌈补办爱尔兰大学文凭🌈LCCI证书定制如何制作一个日本LCA大学院大学学位记🌈合格通知书电子版制作🌈补办爱尔兰大学文凭🌈LCCI证书定制
如何制作一个日本LCA大学院大学学位记🌈合格通知书电子版制作🌈补办爱尔兰大学文凭🌈LCCI证书定制
 
永久可查英国北安普顿大学毕业证(uom学位证书)电子版学位证书留服认证原版一模一样
永久可查英国北安普顿大学毕业证(uom学位证书)电子版学位证书留服认证原版一模一样永久可查英国北安普顿大学毕业证(uom学位证书)电子版学位证书留服认证原版一模一样
永久可查英国北安普顿大学毕业证(uom学位证书)电子版学位证书留服认证原版一模一样
 
【微 tytyqqww 信】网上找黑客改蒙纳士大学__Monash University修改成绩黑客修改成绩,黑客改高考成绩,黑客修改中考成绩1.🎉你是否...
【微 tytyqqww 信】网上找黑客改蒙纳士大学__Monash University修改成绩黑客修改成绩,黑客改高考成绩,黑客修改中考成绩1.🎉你是否...【微 tytyqqww 信】网上找黑客改蒙纳士大学__Monash University修改成绩黑客修改成绩,黑客改高考成绩,黑客修改中考成绩1.🎉你是否...
【微 tytyqqww 信】网上找黑客改蒙纳士大学__Monash University修改成绩黑客修改成绩,黑客改高考成绩,黑客修改中考成绩1.🎉你是否...
 

嵌入式測試驅動開發