SlideShare a Scribd company logo
TDD with Python unittest
          for
     embedded C

            Ben6
           2012-08-28


        www.juluos.org
Agenda
● TDD是什麼?

● 為什麼使用TDD?

● python unittest
  ○ C & Embedded C
● Real Practice
 1. BOS 實際導入
 2. Dummy test and LED Driver
TDD是什麼?
What's TDD?


              測試先行




      意思就是,在開發程式時,
      要以測試的角度來設計。
Red   1. Write a test that fails

       先寫一個測試結果錯誤




TDD
Red            1. Write a test that fails

                  先寫一個測試結果錯誤




TDD
2. Make the code work
                                Green
      使程式可用
Red            1. Write a test that fails

                                    先寫一個測試結果錯誤




3. Eliminate
redundancy
                  TDD
消除冗餘

                  2. Make the code work
    Refactoring                                 Green
                        使程式可用
Red            1. Write a test that fails

                                                        先寫一個測試結果錯誤




3. Eliminate redundancy
                                   TDD
   消除冗餘

                                      2. Make the code work
         Refactoring                                                Green
                                            使程式可用

                          TDD 的開發節奏 "Red, Green, Refactoring"
TDD的觀點


All code is guilty until proven innocent.



任何代碼都是有問題的,直到證明他無誤。
重構 (Refactoring)

Refactoring 是重構一詞,英文以現在進行式,意
味,重構應該不間斷地持續進行。

三項關鍵技能
● 對壞代碼的嗅覺
● 對更好代碼的遠見
● 轉化代碼
請問你有使用TDD嗎?


若有,為什麼使用?
我為什麼使用TDD?


 為了不浪費生命在重複手動測試的事務上

為了有自信重構程式使程式碼更易維護及理解

為了利用測試腳本將產品規格更清除的規範

        更多...
Python unittest
Python unittest
                  $ python sample.py
                  setUp()
                  testCase1()
                  tearDown()
                  .setUp()
                  testCase2()
                  tearDown()
                  .
                  -----------------------------------------
                  -----------------------------
                  Ran 2 tests in 0.000s

                  OK
Python unittest
import random
import unittest

class TestSequenceFunctions(unittest.TestCase):

  def setUp(self):
    self.seq = range(10)

  def test_shuffle(self):
    random.shuffle(self.seq)
    self.seq.sort()
    self.assertEqual(self.seq, range(10))

    self.assertRaises(TypeError, random.shuffle, (1,2,3))

  def test_choice(self):
    element = random.choice(self.seq)
    self.assertTrue(element in self.seq)

  def test_sample(self):
    with self.assertRaises(ValueError):
       random.sample(self.seq, 20)
    for element in random.sample(self.seq, 5):
       self.assertTrue(element in self.seq)

if __name__ == '__main__':
   unittest.main()
Python 與 C

c library: libfoo.so

 int foo(unsigned int r);

python ctypes sample

 from ctypes import *
 foolib = CDLL.LoadLibrary('libfoo.so')
 r = foolib.foo(c_uint(5))
Embedded C

Definitions
● Related to hardware environment


● Ex: A driver
    ■   LED
    ■   Netowrk Interface Card
    ■   VGA Card
    ■   self test
    ■   ...
ctypes
ctypes type    C type                                   Python type
c_bool         _Bool                                    bool (1)
c_char         char                                     1-character string
c_wchar        wchar_t                                  1-character unicode string
c_byte         char                                     int/long
c_ubyte        unsigned char                            int/long
c_short        short                                    int/long
c_ushort       unsigned short                           int/long
c_int          int                                      int/long
c_uint         unsigned int                             int/long
c_long         long                                     int/long
c_ulong        unsigned long                            int/long
c_longlong     __int64 or long long                     int/long
c_ulonglong    unsigned __int64 or unsigned long long   int/long
c_float        float                                    float
c_double       double                                   float
c_longdouble   long double                              float
c_char_p       char * (NUL terminated)                  string or None
c_wchar_p      wchar_t * (NUL terminated)               unicode or None
c_void_p       void *                                   int/long or None
sample ctypes

>>> from ctypes import *
>>> p = create_string_buffer(3)
>>> print sizeof(p), repr(p.raw)
3 'x00x00x00'

>>> p = create_string_buffer("Hello")
>>> print sizeof(p), repr(p.raw)
6 'Hellox00'

>>> print repr(p.value)
'Hello'
sample ctypes


>>> from ctypes import *
>>> p = create_string_buffer("Hello", 10)
>>> print sizeof(p), repr(p.raw)
10 'Hellox00x00x00x00x00'

>>> p.value = "Hi"
>>> print sizeof(p), repr(p.raw)
10 'Hix00lox00x00x00x00x00'
python cdll in different platform


 from ctypes import *
 import sys

 platform = sys.platform
 if sys.platform == "cygwin":
     libc = cdll.LoadLibrary("/bin/cygwin1.dll")
 else:
     libc = CDLL('libc.so.6')
python cdll in different platform (cont.)


 import sys
 from math import log

 def is64bit():
   return log(sys.maxsize, 2) == 63

 arch=32
  if is64bit():
     arch = 64
案例研討(一)

     BOS 實際導入

blibc pytest @ github
CFILES= ../../blibc/itoa.c
OBJS=$(CFILES:.c=.o)
CFLAGS= -I ../../include            Makefile for
BLIBC_SHARED = libbosc.so          unittest blibc
all: $(BLIBC_SHARED)
      python alltests.py

%.o :%.c
     $(CC) -c $< -o $@ $(CFLAGS)

$(BLIBC_SHARED): $(OBJS)
    $(CC) -shared -o $@ $^

clean:
           rm -f $(BLIBC_SHARED) $(OBJS)
import unittest,os
from ctypes import *
app_path = os.path.dirname(os.path.abspath(__file__))
libpathname = os.path.join(app_path, "./libbosc.so")
bc = CDLL(libpathname);
class BOSTest_atoi(unittest.TestCase):
   s = (c_byte*9)()
   c = 427
   def test_atoi(self):                            alltests.py
      # ... next page

def suite_blibc():
  bosTestSuite = unittest.makeSuite(BOSTest_atoi, 'test')
  return bosTestSuite

def main():
  suite1 = suite_blibc()
  alltests = unittest.TestSuite((suite1))
  runner = unittest.TextTestRunner()
  runner.run(alltests);
def test_atoi(self):            test 1 in alltests.py
 # const char *itohex(uint32_t c, char *s, int size, int upper)
 b = bc.itohex(self.c, self.s, c_int(9), c_int(0))
 hex_str = string_at(self.s)
 assert hex_str == "000001ab", "atoi padding hex string"
 assert string_at(b) == "1ab"," atoi incorrect no-zero hex
padding"


                              test 2 in alltests.py
 def test_auto_with_upper(self):
  upper_hex = bc.itohex(self.c, self.s, c_int(9), c_int(1))
  assert string_at(upper_hex) == "1AB", 
    " atoi incorrect no-zero upper hex padding"
實戰演練(一)

Dummy LED(s) Driver
實戰演練(一)發生錯誤的單元測試
 空的測試腳本包含:
   ●      a dummy python test (alltests.py)
           ○ use python ctypes to load lib function
   ●      a sample Makefile to create shared library for python unitest

git clone -b tdd_leds_sample git@github.com:benwei/JuluOS.git tdd_leds
$ cd tdd_leds/tests
$ git checkout -b your_tdd1 a325e85366da5d0d3735863aa983a27700829a28

$ make
python alltests.py
E
======================================================================
ERROR: test_turn_onoff (__main__.BOSTest_led)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "alltests.py", line 21, in test_turn_onoff
   led.turn_on(c_char(0))
TypeError: one character string expected

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)
實戰演練(一)使程式通過測試

  1. 建立 ../drivers/led.c
  2. 並使之通過測試


結果如下:
$ make
cc -c ../drivers/led.c -o ../drivers/led.o -I ../inc
cc -shared -o libled.so ../drivers/led.o
python alltests.py
after turnon 1
after turnoff 0
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
實戰演練(二)
    Refactoring
        及
TDD使用Mock LED(s) Driver
實際演練(二)LED Driver with TDD

Make a test that fails
● Create dummy test function
● Create a Mock LED Device for monitoring
● Add LED turn_on/off api to test function
● Check expect result of LED state

Make code work
● write the operation code for LED

Refactoring
● refined wording, duplicated code, naming ...
Mock LED(s) Device
● 可是一個記憶體位置
● 可為表示狀態的指示器
● 一個簡化後的虛擬裝置

Ex:
uint mock_led = 0;
led_plug(&mock_led, id_1);

     Mock Object 在開發過程十分重要,因為當測試環境愈單純,將會更易於自
 !   動化測試的建構。http://en.wikipedia.org/wiki/Mock_object
實際演練(二)

● 練習題
   ○ 擴充為十個LED 燈,可以同時點亮,也可單獨開關其中
     之一。


完成後原始碼:
$ git checkout tdd_leds_sample
$ git checkout 453b80514da4793f6e608343742ba89bb870dcd6
實際演練(二)TDD完成輸入畫面
git clone -b tdd_leds_sample git@github.com:benwei/JuluOS.git tdd_leds
$ cd tdd_leds/tests
tests$ ls
alltests.py Makefile
tests$ make
cc -c ../drivers/leds.c -o ../drivers/leds.o -I ../inc
cc -shared -o libleds.so ../drivers/leds.o
python alltests.py
after turnon 1
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
實際演練(二)延伸練習

● 使用者可由外部傳入LED Mock Objects

● 使用者可使用不同顏色LED

● 使用者可設任一LED燈亮1~10秒

 ○ 使用python + timer check 來確定其執行時間
Conclusion
TDD 好處

            較少的bug

         減少手動重複測試的時間

            文件檔案

容易改善設計,因不將設計的耦合降低,將無法進行單元測試

  根據測式程式後的記錄,能很清楚知道目前的進度。

   很關卡遊戲,設置問題,填入解答(可不斷精鍊)
        ,獲得完成時的成就感。
1.Write a test
                      that fails




                     TDD
 Eliminate                                      2. Make
redundancy                                     the code
                                                 work

       The mantra of TDD is "Red, green, refactoring"
Ending - Test-driven development
        a programming technique that
       requires you to write actual code
    automated test code simultaneously




        ensures you test your code
 enables you to retest your code quickly and
         easily, since it’s automated
Q&A?
                     Maintain
  write a
 test fails
              TDD?


   Refactor     duplicate
Backlogs
References
Mock Objects for TDD
●   Why and When to Use Mock Objects
●   library unittest mock
●   wikipedia.org/wiki/Mock_object
How python with cli?
cli - interface
                                        ?
● input via arguments

● cli output
   ○ update the specific files
   ○ exit code
   ○ console output


● use unittest program testing cli output
ctypes use global variable in lib
led = CDLL("./libled.so")

v = c_uint.in_dll(led, "_led")
print v.value()

Reference:
http://docs.python.org/library/ctypes.
html#accessing-values-exported-from-dlls
  !   筆者的意見:儘量不要直接存取全域變數;經由封裝函數介面來使用,
             如:uint get_led(void) { return _led; }
loremipsum
A Lorem Ipsum text generator

    pypi.python.org/pypi/loremipsum/1.0.2
>>> from loremipsum import Generator
>>>
>>> sample = file('data/sample.txt').read()
>>> dictionary = file('data/dictionary.txt').read().split()
>>>
>>> g = Generator(sample, dictionary)
>>> g.generate_sentence() #doctest: +ELLIPSIS
(...)
>>>

More Related Content

What's hot (20)

PPTX
Bootloaders (U-Boot)
Omkar Rane
 
PPT
Msp430
Amir Sherman
 
PPTX
Arm v8 instruction overview android 64 bit briefing
Merck Hung
 
PDF
Linux Kernel Overview
Anil Kumar Pugalia
 
PPT
Data race
James Wong
 
PDF
Run Qt on Linux embedded systems using Yocto
Marco Cavallini
 
PDF
Automotive embedded systems part5 v1
Keroles karam khalil
 
PDF
Let's trace Linux Lernel with KGDB @ COSCUP 2021
Jian-Hong Pan
 
PDF
Embedded Linux BSP Training (Intro)
RuggedBoardGroup
 
PPTX
RISC-V Introduction
RISC-V International
 
PDF
Understanding a kernel oops and a kernel panic
Joseph Lu
 
PDF
Linux Porting
Anil Kumar Pugalia
 
PPT
U Boot or Universal Bootloader
Satpal Parmar
 
PPTX
Embedded System Programming on ARM Cortex M3 and M4 Course
FastBit Embedded Brain Academy
 
PDF
Openwrt startup
晓东 杜
 
PPT
Linux SD/MMC Driver Stack
Champ Yen
 
PDF
Q4.11: ARM Architecture
Linaro
 
PDF
Cadence tutorial lab_2_f16
Hoopeer Hoopeer
 
PDF
Embedded C - Lecture 3
Mohamed Abdallah
 
Bootloaders (U-Boot)
Omkar Rane
 
Msp430
Amir Sherman
 
Arm v8 instruction overview android 64 bit briefing
Merck Hung
 
Linux Kernel Overview
Anil Kumar Pugalia
 
Data race
James Wong
 
Run Qt on Linux embedded systems using Yocto
Marco Cavallini
 
Automotive embedded systems part5 v1
Keroles karam khalil
 
Let's trace Linux Lernel with KGDB @ COSCUP 2021
Jian-Hong Pan
 
Embedded Linux BSP Training (Intro)
RuggedBoardGroup
 
RISC-V Introduction
RISC-V International
 
Understanding a kernel oops and a kernel panic
Joseph Lu
 
Linux Porting
Anil Kumar Pugalia
 
U Boot or Universal Bootloader
Satpal Parmar
 
Embedded System Programming on ARM Cortex M3 and M4 Course
FastBit Embedded Brain Academy
 
Openwrt startup
晓东 杜
 
Linux SD/MMC Driver Stack
Champ Yen
 
Q4.11: ARM Architecture
Linaro
 
Cadence tutorial lab_2_f16
Hoopeer Hoopeer
 
Embedded C - Lecture 3
Mohamed Abdallah
 

Similar to Tdd with python unittest for embedded c (20)

PPT
AUTOMATED TESTING USING PYTHON (ATE)
Yuvaraja Ravi
 
PDF
Software development practices in python
Jimmy Lai
 
PDF
Development_C_Extension_with_Pybind11.pdf
Takayuki Suzuki
 
PDF
Py.test
soasme
 
PPT
Automated hardware testing using python
Yuvaraja Ravi
 
PDF
Unit testing on embedded target with C++Test
Engineering Software Lab
 
PDF
SunPy: Python for solar physics
segfaulthunter
 
PDF
Debug - MITX60012016-V005100
Ha Nguyen
 
PDF
Test Driven Development With Python
Siddhi
 
PPTX
Analysis of Testability of a Flight Software Product Line
Dharmalingam Ganesan
 
PDF
MT_01_unittest_python.pdf
Hans Jones
 
PDF
Testing untestable code - ConFoo13
Stephan Hochdörfer
 
PDF
PresentationqwertyuiopasdfghUnittest.pdf
kndemo34
 
PDF
Unit test
David Xie
 
PDF
Python-GTK
Yuren Ju
 
PDF
PyCon2022 - Building Python Extensions
Henry Schreiner
 
PDF
Python Unit Test
David Xie
 
PDF
Diving into byte code optimization in python
Chetan Giridhar
 
PDF
Notes about moving from python to c++ py contw 2020
Yung-Yu Chen
 
PDF
Extending Python - EuroPython 2014
fcofdezc
 
AUTOMATED TESTING USING PYTHON (ATE)
Yuvaraja Ravi
 
Software development practices in python
Jimmy Lai
 
Development_C_Extension_with_Pybind11.pdf
Takayuki Suzuki
 
Py.test
soasme
 
Automated hardware testing using python
Yuvaraja Ravi
 
Unit testing on embedded target with C++Test
Engineering Software Lab
 
SunPy: Python for solar physics
segfaulthunter
 
Debug - MITX60012016-V005100
Ha Nguyen
 
Test Driven Development With Python
Siddhi
 
Analysis of Testability of a Flight Software Product Line
Dharmalingam Ganesan
 
MT_01_unittest_python.pdf
Hans Jones
 
Testing untestable code - ConFoo13
Stephan Hochdörfer
 
PresentationqwertyuiopasdfghUnittest.pdf
kndemo34
 
Unit test
David Xie
 
Python-GTK
Yuren Ju
 
PyCon2022 - Building Python Extensions
Henry Schreiner
 
Python Unit Test
David Xie
 
Diving into byte code optimization in python
Chetan Giridhar
 
Notes about moving from python to c++ py contw 2020
Yung-Yu Chen
 
Extending Python - EuroPython 2014
fcofdezc
 
Ad

More from Benux Wei (9)

PPTX
F9 microkernel app development part 2 gpio meets led
Benux Wei
 
PDF
F9 microkernel app development part 1
Benux Wei
 
PDF
F9 microkernel code reading part 4 memory management
Benux Wei
 
PDF
F9 Microkernel code reading part 2 scheduling
Benux Wei
 
PDF
While software engineer meets 3d printer
Benux Wei
 
PDF
F9 Microkernel code reading - part 1
Benux Wei
 
PDF
Real practice of Networking design on specialized for ARM Cortex-M
Benux Wei
 
PDF
Stm32 f4 first touch
Benux Wei
 
PDF
Preparation for mit ose lab4
Benux Wei
 
F9 microkernel app development part 2 gpio meets led
Benux Wei
 
F9 microkernel app development part 1
Benux Wei
 
F9 microkernel code reading part 4 memory management
Benux Wei
 
F9 Microkernel code reading part 2 scheduling
Benux Wei
 
While software engineer meets 3d printer
Benux Wei
 
F9 Microkernel code reading - part 1
Benux Wei
 
Real practice of Networking design on specialized for ARM Cortex-M
Benux Wei
 
Stm32 f4 first touch
Benux Wei
 
Preparation for mit ose lab4
Benux Wei
 
Ad

Recently uploaded (20)

PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PPTX
Seamless Tech Experiences Showcasing Cross-Platform App Design.pptx
presentifyai
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PDF
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
PDF
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Seamless Tech Experiences Showcasing Cross-Platform App Design.pptx
presentifyai
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 

Tdd with python unittest for embedded c

  • 1. TDD with Python unittest for embedded C Ben6 2012-08-28 www.juluos.org
  • 2. Agenda ● TDD是什麼? ● 為什麼使用TDD? ● python unittest ○ C & Embedded C ● Real Practice 1. BOS 實際導入 2. Dummy test and LED Driver
  • 4. What's TDD? 測試先行 意思就是,在開發程式時, 要以測試的角度來設計。
  • 5. Red 1. Write a test that fails 先寫一個測試結果錯誤 TDD
  • 6. Red 1. Write a test that fails 先寫一個測試結果錯誤 TDD 2. Make the code work Green 使程式可用
  • 7. Red 1. Write a test that fails 先寫一個測試結果錯誤 3. Eliminate redundancy TDD 消除冗餘 2. Make the code work Refactoring Green 使程式可用
  • 8. Red 1. Write a test that fails 先寫一個測試結果錯誤 3. Eliminate redundancy TDD 消除冗餘 2. Make the code work Refactoring Green 使程式可用 TDD 的開發節奏 "Red, Green, Refactoring"
  • 9. TDD的觀點 All code is guilty until proven innocent. 任何代碼都是有問題的,直到證明他無誤。
  • 14. Python unittest $ python sample.py setUp() testCase1() tearDown() .setUp() testCase2() tearDown() . ----------------------------------------- ----------------------------- Ran 2 tests in 0.000s OK
  • 15. Python unittest import random import unittest class TestSequenceFunctions(unittest.TestCase): def setUp(self): self.seq = range(10) def test_shuffle(self): random.shuffle(self.seq) self.seq.sort() self.assertEqual(self.seq, range(10)) self.assertRaises(TypeError, random.shuffle, (1,2,3)) def test_choice(self): element = random.choice(self.seq) self.assertTrue(element in self.seq) def test_sample(self): with self.assertRaises(ValueError): random.sample(self.seq, 20) for element in random.sample(self.seq, 5): self.assertTrue(element in self.seq) if __name__ == '__main__': unittest.main()
  • 16. Python 與 C c library: libfoo.so int foo(unsigned int r); python ctypes sample from ctypes import * foolib = CDLL.LoadLibrary('libfoo.so') r = foolib.foo(c_uint(5))
  • 17. Embedded C Definitions ● Related to hardware environment ● Ex: A driver ■ LED ■ Netowrk Interface Card ■ VGA Card ■ self test ■ ...
  • 18. ctypes ctypes type C type Python type c_bool _Bool bool (1) c_char char 1-character string c_wchar wchar_t 1-character unicode string c_byte char int/long c_ubyte unsigned char int/long c_short short int/long c_ushort unsigned short int/long c_int int int/long c_uint unsigned int int/long c_long long int/long c_ulong unsigned long int/long c_longlong __int64 or long long int/long c_ulonglong unsigned __int64 or unsigned long long int/long c_float float float c_double double float c_longdouble long double float c_char_p char * (NUL terminated) string or None c_wchar_p wchar_t * (NUL terminated) unicode or None c_void_p void * int/long or None
  • 19. sample ctypes >>> from ctypes import * >>> p = create_string_buffer(3) >>> print sizeof(p), repr(p.raw) 3 'x00x00x00' >>> p = create_string_buffer("Hello") >>> print sizeof(p), repr(p.raw) 6 'Hellox00' >>> print repr(p.value) 'Hello'
  • 20. sample ctypes >>> from ctypes import * >>> p = create_string_buffer("Hello", 10) >>> print sizeof(p), repr(p.raw) 10 'Hellox00x00x00x00x00' >>> p.value = "Hi" >>> print sizeof(p), repr(p.raw) 10 'Hix00lox00x00x00x00x00'
  • 21. python cdll in different platform from ctypes import * import sys platform = sys.platform if sys.platform == "cygwin": libc = cdll.LoadLibrary("/bin/cygwin1.dll") else: libc = CDLL('libc.so.6')
  • 22. python cdll in different platform (cont.) import sys from math import log def is64bit(): return log(sys.maxsize, 2) == 63 arch=32 if is64bit(): arch = 64
  • 23. 案例研討(一) BOS 實際導入 blibc pytest @ github
  • 24. CFILES= ../../blibc/itoa.c OBJS=$(CFILES:.c=.o) CFLAGS= -I ../../include Makefile for BLIBC_SHARED = libbosc.so unittest blibc all: $(BLIBC_SHARED) python alltests.py %.o :%.c $(CC) -c $< -o $@ $(CFLAGS) $(BLIBC_SHARED): $(OBJS) $(CC) -shared -o $@ $^ clean: rm -f $(BLIBC_SHARED) $(OBJS)
  • 25. import unittest,os from ctypes import * app_path = os.path.dirname(os.path.abspath(__file__)) libpathname = os.path.join(app_path, "./libbosc.so") bc = CDLL(libpathname); class BOSTest_atoi(unittest.TestCase): s = (c_byte*9)() c = 427 def test_atoi(self): alltests.py # ... next page def suite_blibc(): bosTestSuite = unittest.makeSuite(BOSTest_atoi, 'test') return bosTestSuite def main(): suite1 = suite_blibc() alltests = unittest.TestSuite((suite1)) runner = unittest.TextTestRunner() runner.run(alltests);
  • 26. def test_atoi(self): test 1 in alltests.py # const char *itohex(uint32_t c, char *s, int size, int upper) b = bc.itohex(self.c, self.s, c_int(9), c_int(0)) hex_str = string_at(self.s) assert hex_str == "000001ab", "atoi padding hex string" assert string_at(b) == "1ab"," atoi incorrect no-zero hex padding" test 2 in alltests.py def test_auto_with_upper(self): upper_hex = bc.itohex(self.c, self.s, c_int(9), c_int(1)) assert string_at(upper_hex) == "1AB", " atoi incorrect no-zero upper hex padding"
  • 28. 實戰演練(一)發生錯誤的單元測試 空的測試腳本包含: ● a dummy python test (alltests.py) ○ use python ctypes to load lib function ● a sample Makefile to create shared library for python unitest git clone -b tdd_leds_sample [email protected]:benwei/JuluOS.git tdd_leds $ cd tdd_leds/tests $ git checkout -b your_tdd1 a325e85366da5d0d3735863aa983a27700829a28 $ make python alltests.py E ====================================================================== ERROR: test_turn_onoff (__main__.BOSTest_led) ---------------------------------------------------------------------- Traceback (most recent call last): File "alltests.py", line 21, in test_turn_onoff led.turn_on(c_char(0)) TypeError: one character string expected ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1)
  • 29. 實戰演練(一)使程式通過測試 1. 建立 ../drivers/led.c 2. 並使之通過測試 結果如下: $ make cc -c ../drivers/led.c -o ../drivers/led.o -I ../inc cc -shared -o libled.so ../drivers/led.o python alltests.py after turnon 1 after turnoff 0 . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
  • 30. 實戰演練(二) Refactoring 及 TDD使用Mock LED(s) Driver
  • 31. 實際演練(二)LED Driver with TDD Make a test that fails ● Create dummy test function ● Create a Mock LED Device for monitoring ● Add LED turn_on/off api to test function ● Check expect result of LED state Make code work ● write the operation code for LED Refactoring ● refined wording, duplicated code, naming ...
  • 32. Mock LED(s) Device ● 可是一個記憶體位置 ● 可為表示狀態的指示器 ● 一個簡化後的虛擬裝置 Ex: uint mock_led = 0; led_plug(&mock_led, id_1); Mock Object 在開發過程十分重要,因為當測試環境愈單純,將會更易於自 ! 動化測試的建構。http://en.wikipedia.org/wiki/Mock_object
  • 33. 實際演練(二) ● 練習題 ○ 擴充為十個LED 燈,可以同時點亮,也可單獨開關其中 之一。 完成後原始碼: $ git checkout tdd_leds_sample $ git checkout 453b80514da4793f6e608343742ba89bb870dcd6
  • 34. 實際演練(二)TDD完成輸入畫面 git clone -b tdd_leds_sample [email protected]:benwei/JuluOS.git tdd_leds $ cd tdd_leds/tests tests$ ls alltests.py Makefile tests$ make cc -c ../drivers/leds.c -o ../drivers/leds.o -I ../inc cc -shared -o libleds.so ../drivers/leds.o python alltests.py after turnon 1 .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
  • 35. 實際演練(二)延伸練習 ● 使用者可由外部傳入LED Mock Objects ● 使用者可使用不同顏色LED ● 使用者可設任一LED燈亮1~10秒 ○ 使用python + timer check 來確定其執行時間
  • 37. TDD 好處 較少的bug 減少手動重複測試的時間 文件檔案 容易改善設計,因不將設計的耦合降低,將無法進行單元測試 根據測式程式後的記錄,能很清楚知道目前的進度。 很關卡遊戲,設置問題,填入解答(可不斷精鍊) ,獲得完成時的成就感。
  • 38. 1.Write a test that fails TDD Eliminate 2. Make redundancy the code work The mantra of TDD is "Red, green, refactoring"
  • 39. Ending - Test-driven development a programming technique that requires you to write actual code automated test code simultaneously ensures you test your code enables you to retest your code quickly and easily, since it’s automated
  • 40. Q&A? Maintain write a test fails TDD? Refactor duplicate
  • 42. References Mock Objects for TDD ● Why and When to Use Mock Objects ● library unittest mock ● wikipedia.org/wiki/Mock_object
  • 43. How python with cli? cli - interface ? ● input via arguments ● cli output ○ update the specific files ○ exit code ○ console output ● use unittest program testing cli output
  • 44. ctypes use global variable in lib led = CDLL("./libled.so") v = c_uint.in_dll(led, "_led") print v.value() Reference: http://docs.python.org/library/ctypes. html#accessing-values-exported-from-dlls ! 筆者的意見:儘量不要直接存取全域變數;經由封裝函數介面來使用, 如:uint get_led(void) { return _led; }
  • 45. loremipsum A Lorem Ipsum text generator pypi.python.org/pypi/loremipsum/1.0.2 >>> from loremipsum import Generator >>> >>> sample = file('data/sample.txt').read() >>> dictionary = file('data/dictionary.txt').read().split() >>> >>> g = Generator(sample, dictionary) >>> g.generate_sentence() #doctest: +ELLIPSIS (...) >>>