You are on page 1of 74

BỘ GIÁO DỤC VÀ ĐÀO TẠO

TRƯỜNG ĐẠI HỌC NGOẠI NGỮ - TIN HỌC TP. HỒ CHÍ MINH
KHOA CÔNG NGHỆ THÔNG TIN

BÁO CÁO THỰC TẬP TỐT NGHIỆP

XÂY DỰNG ỨNG DỤNG WEB VỚI SHINY


TRONG R VÀ THAO TÁC VỚI DỮ LIỆU TRONG
PYTHON

Giảng viên hướng dẫn: Trần Khải Thiện


Sinh viên thực hiện: Hoàng Gia Bảo
Mã số sinh viên: 20DH111921
Chuyên ngành: Công nghệ phần mềm
Đơn vị thực tập: CÔNG TY CỔ PHẦN PHẦN MỀM 4P
Khóa: 2020 - 2024

TP.HCM, tháng 03 năm 2024

1
BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC NGOẠI NGỮ - TIN HỌC TP. HỒ CHÍ MINH
KHOA CÔNG NGHỆ THÔNG TIN

BÁO CÁO THỰC TẬP TỐT NGHIỆP

XÂY DỰNG ỨNG DỤNG WEB VỚI SHINY


TRONG R VÀ THAO TÁC VỚI DỮ LIỆU TRONG
PYTHON

Giảng viên hướng dẫn: Trần Khải Thiện


Sinh viên thực hiện: Hoàng Gia Bảo
Mã số sinh viên: 20DH111921
Chuyên ngành: Công nghệ phần mềm
Đơn vị thực tập: CÔNG TY CỔ PHẦN PHẦN MỀM 4P
Khóa: 2020 - 2024

TP.HCM, tháng 03 năm 2024

i
LỜI CẢM ƠN

Em xin gửi lời cảm ơn chân thành đến Công ty Cổ phần Phần mềm 4P và thầy
Trần Khải Thiện - giảng viên hướng dẫn, về cơ hội thực tập thiết thực và quý báu mà
em đã được trải nghiệm. Em muốn bày tỏ lòng biết ơn sâu sắc và lòng tạ ơn tới hai
bên đã tạo điều kiện và hỗ trợ em trong suốt quá trình thực tập.
Cơ hội này không chỉ giúp em áp dụng kiến thức học được trong môi trường
thực tế mà còn mang đến cho em những trải nghiệm thực tế và kinh nghiệm quý báu
trong lĩnh vực công nghệ thông tin. Em rất biết ơn về sự tận tâm và kiên nhẫn của
Công ty Cổ phần Phần mềm 4P cũng như sự hướng dẫn chỉ bảo chân thành từ thầy
Trần Khải Thiện.
Em cảm nhận được giá trị của sự hỗ trợ tận tâm từ Công ty Cổ phần Phần mềm
4P
và sự hướng dẫn chuyên sâu từ thầy Trần Khải Thiện đã giúp em vượt qua những
thách thức trong quá trình thực tập. Những kiến thức và kỹ năng em học được sẽ là
nền tảng vững chắc cho sự phát triển tương lai của em trong lĩnh vực này.
Một lần nữa, em xin bày tỏ lòng biết ơn chân thành và sâu sắc đến Công ty Cổ
phần Phần mềm 4P và thầy Trần Khải Thiện về cơ hội thực tập và sự hướng dẫn tận
tâm. Em hứa sẽ luôn ghi nhớ và trân trọng những giá trị và kinh nghiệm mà em đã
được học hỏi từ hai bên này.

ii
LỜI MỞ ĐẦU

Trong bước tiến của cuộc cách mạng công nghệ, Công ty Cổ phần Phần mềm 4P là
công ty chuyên gia về phần mềm, lập trình lập trình thiết kế website thương mại, triển
khai lắp đặt các hệ thống mạng và xây dựng các chiến lược kinh doanh tiếp thị trực
tuyến. Công ty được thành lập với sứ mệnh cung cấp đến khách hàng những giải
pháp, ứng dụng công nghệ thông tin hiệu quả và chuyên nghiệp nhất. Mỗi sản phẩm,
dịch vụ của Công ty Cổ phần Phần mềm 4P được tạo ra và cung cấp luôn thoả mãn
các tiêu chí của khách hàng về cả chất lượng và cả giá cả.
Với ước mơ xây dựng một phần mềm đến tay khách hàng, tôi xin chia sẻ
những góc nhìn và sự học hỏi của mình từ việc thực tập tại Công ty Cổ phần Phần
mềm 4P thông qua báo cáo này.

iii
NHẬN XÉT CỦA GIẢNG VIÊN HƯỚNG DẪN

.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
TPHCM, Ngày …… tháng …… năm 20….
Giảng viên hướng dẫn
(Ký tên, đóng dấu)

TS. Trần Khải Thiện

iv
NHẬN XÉT CỦA CƠ QUAN THỰC TẬP

.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
.........................................................................................................................................
TPHCM, Ngày …… tháng …… năm 20….
Xác nhận của đơn vị thực tập
(Ký tên, đóng dấu)

v
MỤC LỤC

CHƯƠNG I: GIỚI THIỆU..........................................................................................................


1. Giới thiệu về công ty.............................................................................................................
1.1 Sơ lược về công ty...........................................................................................................
1.2 Dịch vụ phần mềm..........................................................................................................
1.3 Vai trò của bản thân trong công ty...............................................................................
CHƯƠNG II: NỘI DUNG THỰC TẬP.....................................................................................
1. INTERMEDIATE PYTHON..............................................................................................
1.1. Matplotlib...........................................................................................................................
1.1.1. Sức Mạnh của Các Biểu Đồ Đẹp Mắt.................................................................
1.1.2. Giới Thiệu về Matplotlib......................................................................................
1.1.3. Trực Quan Hóa Dữ Liệu với Matplotlib............................................................
1.1.4. Khám Phá Biểu Đồ Phân Tán.............................................................................
1.1.5. Sử Dụng Matplotlib để Xây Dựng Histogram...................................................
1.1.6. Tùy chỉnh các biểu đồ...........................................................................................
1.2. Dictionaries & Pandas.......................................................................................................
1.2.1. Định nghĩa Dictionary..........................................................................................
1.2.2. Định nghĩa Pandas DataFrame:..........................................................................
1.2.3. Ứng Dụng:.............................................................................................................
1.3. Logic, Control Flow and Filtering....................................................................................
1.3.1. Comparison Operators:.......................................................................................
1.3.2. Boolean Operators:...............................................................................................
1.3.3. if:............................................................................................................................
1.3.4. else:.........................................................................................................................
1.3.5. elif:..........................................................................................................................
1.3.6. Filtering pandas DataFrames:.............................................................................
1.4. Loops...................................................................................................................................
1.4.1. Vòng lặp white......................................................................................................
1.4.2. Vòng lặp for.........................................................................................................
1.4.3. Loop Data Structures.........................................................................................
1.5. Case Study: Hacker Statistics.........................................................................................
1.5.1. Ramdom Number...............................................................................................
1.5.2. Random Walk.....................................................................................................
2. UNIT TEST BY PYTHON................................................................................................
2.1. Unit testing basics............................................................................................................

vi
2.1.1. Ý Nghĩa của Unit Test:.......................................................................................
2.1.2. Viết một bài kiểm tra đơn vị đơn giản bằng pytest.........................................
2.1.3. Hiểu báo cáo kết quả kiểm tra...........................................................................
2.2. Intermediate unit testing.................................................................................................
2.2.1. Nắm vững các câu khẳng định..........................................................................
2.2.2. Kiểm tra các ngoại lệ thay vì giá trị trả về.......................................................
2.2.3. Chức năng đã được thử nghiệm tốt..................................................................
2.2.4. Kiểm tra các ngoại lệ thay vì trả về giá trị.......................................................
2.2.5. Test Driven Development (TDD).......................................................................
2.3. Test Organization and Execution...................................................................................
2.3.1. Làm thế nào để tổ chức số lượng bài kiểm tra ngày càng tăng?....................
2.3.2. Làm chủ việc thực hiện kiểm thử......................................................................
2.3.3. Thất bại dự kiến và bỏ qua có điều kiện...........................................................
2.3.4. Continuous integration and code coverage......................................................
2.4. Testing Models, Plots and Much More..........................................................................
2.4.1. Ngoài khẳng định: thiết lập và chia nhỏ...........................................................
2.4.2. Mocking...............................................................................................................
2.4.3. Testing models.....................................................................................................
2.4.4. Testing plots........................................................................................................
CHƯƠNG 3: TỔNG KẾT.........................................................................................................
1. Khó khăn và thuận lợi........................................................................................................
1.1 Khó khăn.......................................................................................................................
1.2 Thuận lợi.......................................................................................................................
2. Bài học kinh nghiệm cho bản thân....................................................................................
2.1 Về kiến thức..................................................................................................................
2.2 Về kỹ năng.....................................................................................................................
2.3 Về thái độ - ý thức - tác phong....................................................................................
3. Tổng kết...............................................................................................................................
PHỤ LỤC....................................................................................................................................
TÀI LIỆU THAM KHẢO..........................................................................................................

vii
DANH MỤC CÁC BẢNG BIỂU

viii
DANH MỤC CÁC BẢNG HÌNH

Hình 1 Ví dụ về biểu đồ..................................................................................................................


Hình 2 Ví dụ về Matplotlib.............................................................................................................
Hình 3 Ví dụ về biểu đò phân tán...................................................................................................
Hình 4 Ví dụ về xây dựng Histogram.............................................................................................
Hình 5 Ví dụ về If...........................................................................................................................
Hình 6 Ví dụ về Esle.....................................................................................................................
Hình 7 Ví dụ Elif..........................................................................................................................
Hình 8 Ví dụ về ramdom walk.....................................................................................................
Hình 9 Ví dụ về tổng số tails........................................................................................................
Hình 10 Ví dụ về tổng số tails......................................................................................................
Hình 11 Vòng đời của funciton....................................................................................................
Hình 12 Ví dụ vè hàm Row_to_ list.............................................................................................
Hình 13 Ví dụ vè hàm Row_to_ list 2..........................................................................................
Hình 14 Ví dụ vè hàm Row_to_ list 3..........................................................................................
Hình 15 Kiểm thử trên console.....................................................................................................
Hình 16 Ví dụ vè test_row_to_list.py..........................................................................................
Hình 17 Ví dụ về test_row_to_list.py 2........................................................................................
Hình 18 Ví dụ về test_row_to_list.py 3.......................................................................................
Hình 19 Ví dụ về test_row_to_list.py 4........................................................................................
Hình 20 Ví dụ về test_row_to_list.py 5........................................................................................
Hình 21 Ví dụ về test_row_to_list.py 6........................................................................................
Hình 22 Hiển thị báo cáo kết quả kiểm thử..................................................................................
Hình 23 Thông tin chung của kiểm thử........................................................................................
Hình 24 Kết quả kiểm thử............................................................................................................
Hình 25 Khi thêm câu lệnh assert.................................................................................................
Hình 26 Trường hợp nên kiểm lại................................................................................................
Hình 27 Kiểm thử đầu tiên đã qua, thứ hai thất bại và thứ ba đã qua..........................................
Hình 28 Các thông tin kiểm thử thất bại......................................................................................
Hình 29 Dòng đánh dấu E là các ngoại lệ....................................................................................
Hình 30 Hiển thị giá trị trở về......................................................................................................
Hình 31 Tóm tắt kết quả kiểm thử................................................................................................
Hình 32 Tham số thông báo tùy chọn...........................................................................................
Hình 33 Thêm một thông báo vào một bài kiểm tra đơn vị.........................................................
Hình 34 Báo cáo kết quả kiểm tra với thông báo.........................................................................
Hình 35 Cảnh báo về giá trị trả về kiểu float!..............................................................................
Hình 36 Nhiều câu lệnh assert trong một bài kiểm tra đơn vị......................................................
Hình 37 Ví dụ về hàm...................................................................................................................
Hình 38 Kiểm tra ngoại lệ của hàm..............................................................................................
Hình 39 Cấu trúc lý thuyết của câu lệnh with..............................................................................
Hình 40 Cấu trúc lý thuyết của câu lệnh with 2...........................................................................
Hình 41 Kiểm tra thông điệp lỗi...................................................................................................
Hình 42 Ví dụ cách kiểm tra độ dài, không phải giá trị...............................................................
Hình 43 Cách kiểm tra độ dài, không phải giá trị.........................................................................
Hình 44 Kiểm tra đối số và giá trị trả về mong đợi......................................................................
Hình 45 Số lượng đối số để kiểm tra loại 1..................................................................................
Hình 46 Số lượng đối số để kiểm tra loại 2..................................................................................
Hình 47 Đối số bình thường.........................................................................................................
Hình 48 Hàm split_into_training_and_testing_sets mong đợi mảng NumPy 2 chiều.................
ix
Hình 49 Hàm pytest.raises():........................................................................................................
Hình 50 Kiểm tra thông báo lỗi....................................................................................................
Hình 51 Bad Arguments...............................................................................................................
Hình 52 Special Arguments..........................................................................................................
Hình 53 Normal Arguments.........................................................................................................
Hình 54 Viết unit test và hoàn thiện yêu cầu hàm........................................................................
Hình 55 Chạy test và quan sát lỗi.................................................................................................
Hình 56 Hàm split_into_training_and_testing_sets()...................................................................
Hình 57 Bài kiểm thử test_preprocessing_helpers.py..................................................................
Hình 58 Quy tắc chung là cho mỗi module Python my_module.py.............................................
Hình 59 Thư mục này chứa các gói (packages)...........................................................................
Hình 60 Máy chủ CI.....................................................................................................................
Hình 61 Sử dụng cờ "-x"..............................................................................................................
Hình 62 Pytest gán một ID...........................................................................................................
Hình 63 Sử dụng tùy chọn "-k"....................................................................................................
Hình 64 Thất bại dự kiến (xfail)...................................................................................................
Hình 65 Bỏ qua có điều kiện (skipif)...........................................................................................
Hình 66 Báo cáo lý do..................................................................................................................
Hình 67 Tạo tệp .travis.yml..........................................................................................................
Hình 68 Đẩy tệp .travis.yml lên GitHub.......................................................................................
Hình 69 Sửa đổi .travis.yml..........................................................................................................
Hình 70 Ví dụ Fixture raw_and_clean_data_file().......................................................................
Hình 71 Ví dụ sử dụng fixture tmpdir tạo thư mục tạm và tự động dọn dẹp...............................
Hình 72 Chạy test bình thường: pytest –mpl................................................................................
Hình 73 Chứng chỉ Intermediate..................................................................................................
Hình 74 Chứng chỉ Unit Testing for Data Science in Python......................................................

x
DANH MỤC CÁC TỪ VIẾT TẮT

Từ viết tắt Ý nghĩa


Continuous Integration là một thực hành của
CI
việc liên tục tích hợp những thay đổi tạo ra
với project và test lại nó hàng ngày hoặc
thường xuyên hơn.
TDD (Test Driven Development) là một
TDD
phương thức làm việc, hay một quy trình
viết mã hiện đại.

xi
TRƯỜNG ĐẠI HỌC NGOẠI NGỮ - TIN HỌC
TP. HỒ CHÍ MINH

KHOA CÔNG NGHỆ THÔNG TIN

SỔ NHẬT KÝ THỰC TẬP

Họ tên HSSV: Hoàng Gia Bảo

Lớp: PM2006

Ngành: Công nghệ thông tin

Cơ quan thực tập: Công ty Cổ phần Phần mềm 4P

Thời gian thực tập: Từ …/…/20… đến …/…/20…

Tháng 03/2024
* Lưu ý: Nội dung thực tập được liệt kê và đánh giá theo từng tuần trong đợt thực tập.

Chữ ký Nhận xét của Nội dung thực tập Thời gian Tuần
Người HD
của đơn vị đơn vị thực tập
thực tập

Tìm hiểu về công ty Cổ phần Phần mềm 4P Từ


cũng như các quy trình làm việc trong công
ty
01/02/2024 1

đến
03/02/2024

Xây dựng lịch trình thực hiện, xác định các


bước cụ thể trong từng tuần
Đọc các tài liệu hướng dẫn về công nghệ sử
dụng
Từ
Tìm hiểu và làm bài tập của các chương
trong khóa Matplotlib 05/02/2024 2

đến
09/02/2024

Tìm hiểu và làm bài tập của các chương


trong khóa Dictionaries & Pandas
Từ

15/02/2024 3

đến
17/02/2024

Tìm hiểu và làm bài tập của các chương


trong khóa Logic, Control Flow and
Filtering
Từ

19/02/2024 4

đến
24/02/2024
Tìm hiểu và làm bài tập của các chương
trong khóa Loops & Case Study: Hacker
Statistics Từ 04/03/2024

Đến
5
02/03/2024

Tìm hiểu và làm bài tập của các chương


trong khóa Unit testing basics & Từ
Intermediate unit testing
04/03/2024

đến 6
09/03/2024

Tìm hiểu và làm bài tập của các chương


trong khóa Test Organization and Execution Từ
& Testing Models, Plots and Much More
11/03/2024

đến 7
16/03/2024

 Hoàn thiện các bài còn thiếu để nhận


các chứng chỉ của các khóa học Từ
Chuẩn bị báo cáo và tài liệu cuối cùng cho
việc kết thúc thực tập 18/03/2024

đến 8
23/03/2024

TP.HCM, ngày …...tháng ….. năm 20….


Trưởng đơn vị quản lý thực tập
PHẠM THỊ THANH HUYỀN
TRƯỜNG ĐẠI HỌC NGOẠI NGỮ - TIN
HỌC TP. HỒ CHÍ MINH
Địa chỉ: 828 Sư Vạn Hạnh, Phường 13, Quận 10, TP. Hồ Chí Minh
Điện thoại: (+84 28) 38 632 052 - 38 629 232
Fax: (+84 28) 38 650 991
Email: contact@huflit.edu.vn

PHIẾU NHẬN XÉT SINH VIÊN THỰC TẬP


(Vui lòng đánh dấu [x] vào ô thích hợp)

Họ và tên sinh viên: Hoàng Gia Bảo Lớp: PM2006

Cơ quan tiếp nhận: Công ty Cổ phần Phần mềm 4P

1. Nhận xét của cơ quan về chất lượng công việc được giao:

Các công việc được giao:


 Yếu  Khá  Hoàn thành xuất sắc
 Trung bình  Tốt

Hoàn tất công việc được giao:


 Hoàn thành đúng  Thỉnh thoảng đúng  Không đúng thời hạn

Tính hữu hiệu của đợt thực tập đối với cơ quan
 Giúp ích ít  Có giúp ích nhiều
 Không giúp ích gì mấy cho hoạt động của cơ quan

2. Nhận xét của cơ quan về bản thân sinh viên

Năng lực chuyên môn sử dụng vào công việc được giao ở mức:
 Trung bình  Giỏi
 Yếu  Khá

Tinh thần, thái độ đối với công việc được giao:

 Thiếu tích cực  Bình thường  Tích cực

Đảm bảo kỷ luật lao động (giờ giấc lao động, nghỉ làm,…)
 Tốt
 Trung bình
 Kém
Thái độ đối với cán bộ, công nhân viên trong cơ quan:
 Chan hòa  Không có gì đáng nói  Rụt rè
3. Nếu được, xin cho biết một “thành tích nổi bật” của sinh viên (nếu không có,
xin bỏ qua)
............................................................................................................................................
............................................................................................................................................
4. Các nhận xét khác (nếu có)
............................................................................................................................................
............................................................................................................................................
5. Đánh giá (theo thang điểm 10)

a) Điểm chuyên cần, phong cách: …………. b) Điểm chuyên môn:


…………..

Vui lòng xin cho biết thêm:


- Họ và tên người nhận xét: Phạm Thị Thanh Huyền
- Chức vụ trong cơ quan: Phó Giám Đốc

Trưởng đơn vị Ngày …. Tháng…. Năm 20……

(ký tên, đóng dấu và ghi rõ họ tên) Người nhận xét

(Ký và ghi rõ họ tên)

PHẠM THỊ THANH HUYỀN

PHẠM THỊ THANH HUYỀN


CHƯƠNG I: GIỚI THIỆU

1. Giới thiệu về công ty

1.1 Sơ lược về công ty

Được thành lập vào năm 2004, Công ty Cổ phần Phần mềm 4P là công ty
chuyên gia về gia công phần mềm, lập trình thiết kế website thương mại, triển khai
lắp đặt các hệ thống mạng và xây dựng các chiến lược kinh doanh tiếp thị trực tuyến.
Công ty phần mềm 4PSoft được thành lập với sứ mệnh cung cấp đến khách hàng
những giải pháp, ứng dụng công nghệ thông tin hiệu quả và chuyên nghiệp nhất.

1.2 Dịch vụ phần mềm

Công ty Cổ phần Phần mềm 4P mang đến một loạt dịch vụ đa dạng, tạo nên sự
đột phá và tiên tiến trong nhiều lĩnh vực, mỗi sản phẩn dịch vụ được tạo ra và cung
cấp là thành quả của sự kết hợp giữa kinh nghiệm và những công nghệ tiên tiến nhất
thỏa mãn các tiêu chí về chất lượng, giá cả, đầy đủ tài liệu hướng dẫn và tuân thủ chế
độ bảo hành và hỗ trợ kĩ thuật mọi lúc mọi nơi
- Dịch vụ thiết kế website: Công ty sử dụng công nghệ mới, giúp thiết kế
website theo đúng chuẩn Google với chương trình CMS – Hệ thống quản lí nội dụng
website, nhờ thế có thể thay đổi thông tin trên website bằng những thao tác đơn giản
mà không cần nhờ sự hỗ trợ của 4PSoft
- Thiết kế phần mềm: Các giải pháp về ERP giúp các doanh nghiệp quản trị tài
nguyên một cách hiệu quả, ngoài ra còn có các hệ thống tính lương và chấm công
giúp các doanh nghiệp tiết kiệm nhiều thời gian và công sức.
- Hoạt động chuyên môn, khoa học và công nghệ khác: Công ty cung cấp các
dịch vụ chuyên môn, khoa học và công nghệ đa dạng, đáp ứng nhu cầu đa dạng của
khách hàng.

1.3 Vai trò của bản thân trong công ty

Inter Tester bao gồm:


Thực hiện kiểm thử phần mềm: thực hiện các test case để kiểm tra chức năng, hiệu
suất, bảo mật và khả năng tương thích của phần mềm.
Báo cáo lỗi: Khi phát hiện lỗi, sẽ báo cáo cho đội ngũ phát triển để họ sửa lỗi.
Tham gia vào quá trình phát triển phần mềm: tham gia vào các cuộc họp và thảo luận
về kế hoạch phát triển phần mềm để đảm bảo phần mềm đáp ứng nhu cầu của người
dùng.
Đề xuất cải tiến: đề xuất các cải tiến để nâng cao chất lượng phần mềm.
CHƯƠNG II: NỘI DUNG THỰC TẬP

1. INTERMEDIATE PYTHON

1.1. Matplotlib
Trực quan hóa dữ liệu là một kỹ năng cơ bản trong phân tích dữ liệu, giúp khám phá
và truyền đạt những thông tin quan trọng từ dữ liệu. Trong báo cáo này, chúng ta sẽ
tìm hiểu về các khái niệm cơ bản của trực quan hóa dữ liệu bằng cách sử dụng
Matplotlib, một thư viện mạnh mẽ trong ngôn ngữ lập trình Python. Qua ví dụ và giải
thích, chúng ta sẽ hiểu cách Matplotlib hỗ trợ tạo ra các loại biểu đồ khác nhau, giúp
khám phá và hiểu dữ liệu một cách hiệu quả.
Trực quan hóa dữ liệu là một phần không thể thiếu trong quá trình phân tích dữ liệu,
giúp các nhà khoa học dữ liệu hiểu được các tập dữ liệu phức tạp và rút ra những
thông tin quan trọng. Bằng cách trực quan hóa dữ liệu, chúng ta có thể nhận diện các
mẫu, xu hướng và mối quan hệ mà có thể không rõ ràng từ dữ liệu gốc. Hơn nữa, trực
quan hóa hiệu quả tăng cường việc truyền đạt các kết quả cho các bên liên quan, giúp
ra quyết định có căn cứ.

1.1.1. Sức Mạnh của Các Biểu Đồ Đẹp Mắt

Các biểu đồ đẹp mắt, ví dụ như công việc của các chuyên gia như Hans Rosling, có
khả năng truyền đạt những câu chuyện hấp dẫn thông qua trực quan hóa dữ liệu. Biểu
đồ bong bóng nổi tiếng của Hans Rosling, minh họa mối quan hệ giữa GDP bình
quân đầu người và tuổi thọ, thể hiện cách biểu đồ thú vị có thể thu hút sự chú ý của
khán giả và giúp dữ liệu nói lên chính nó.
Hình 1 Ví dụ về biểu đồ

1.1.2. Giới Thiệu về Matplotlib

Matplotlib là một trong những thư viện hàng đầu trong ngôn ngữ lập trình Python cho
trực quan hóa dữ liệu. Bằng cách sử dụng gói con pyplot của nó, Matplotlib cung cấp
các công cụ mạnh mẽ để tạo ra các loại biểu đồ khác nhau. Theo quy ước, pyplot
được nhập vào như plt, giúp việc viết mã trở nên ngắn gọn và dễ đọc hơn. Với
Matplotlib, chúng ta có thể tạo ra biểu đồ đường, biểu đồ phân tán, biểu đồ cột và
nhiều loại biểu đồ khác, mở ra nhiều lựa chọn trực quan hóa.

1.1.3. Trực Quan Hóa Dữ Liệu với Matplotlib

Để minh họa khả năng của Matplotlib, chúng ta bắt đầu bằng việc trực quan hóa sự
phát triển dân số thế giới theo thời gian. Sử dụng các danh sách các năm và dân số
tương ứng, chúng ta tạo ra một biểu đồ đường bằng cách sử dụng plt.plot(). Phương
pháp đánh giá lười biếng của Matplotlib trì hoãn việc hiển thị biểu đồ cho đến khi cần
thiết, cho phép tùy chỉnh trước khi trình bày biểu đồ.
Hình 2 Ví dụ về Matplotlib

1.1.4. Khám Phá Biểu Đồ Phân Tán

Ngoài biểu đồ đường, Matplotlib cũng hỗ trợ biểu đồ phân tán, thể hiện các điểm dữ
liệu mà không kết nối chúng với nhau. Biểu đồ phân tán cung cấp một cách hiển thị
minh bạch của dữ liệu và thường được ưa chuộng để trực quan hóa mối quan hệ giữa
các biến. Bằng cách sử dụng plt.scatter(), chúng ta có thể dễ dàng tạo ra các biểu đồ
phân tán để khám phá phân phối và mẫu mực dữ liệu.

Hình 3 Ví dụ về biểu đò phân tán

1.1.5. Sử Dụng Matplotlib để Xây Dựng Histogram


Matplotlib là một thư viện phổ biến trong Python được sử dụng để tạo ra các biểu đồ,
bao gồm cả histogram. Để tạo một histogram trong Matplotlib, chúng ta sử dụng hàm
hist() trong gói pyplot. Chúng ta cung cấp dữ liệu cần biểu diễn và chỉ định số lượng
bins mà chúng ta muốn sử dụng. Matplotlib sẽ tự động tính toán các khoảng và vẽ
histogram tương ứng.

Hình 4 Ví dụ về xây dựng Histogram

1.1.6. Tùy chỉnh các biểu đồ

Trong quá trình làm việc với dữ liệu, việc tạo ra các biểu đồ trực quan là một phần
quan trọng để hiểu rõ hơn về dữ liệu và truyền đạt thông điệp của chúng. Python cung
cấp các công cụ mạnh mẽ để tạo ra các biểu đồ đẹp và có ý nghĩa, và việc tùy chỉnh
các biểu đồ là một kỹ năng quan trọng mà mọi người nên nắm vững.
Trong Python, chúng ta thường sử dụng thư viện Matplotlib để tạo ra các biểu đồ.
Với Matplotlib, chúng ta có thể điều chỉnh mọi chi tiết của biểu đồ, từ màu sắc và
hình dạng cho đến nhãn và tiêu đề. Việc tùy chỉnh giúp biểu đồ trở nên rõ ràng hơn
và dễ hiểu hơn đối với người đọc.
Bằng cách sử dụng các hàm như xlabel, ylabel, và title, chúng ta có thể thêm nhãn và
tiêu đề vào biểu đồ để mô tả rõ ràng về dữ liệu được biểu diễn. Ngoài ra, chúng ta
cũng có thể tinh chỉnh các trục của biểu đồ bằng cách sử dụng các hàm như xticks và
yticks để điều chỉnh các điểm chia trục và nhãn của chúng.
Tùy chỉnh biểu đồ không chỉ giúp biểu đồ trở nên hấp dẫn hơn mà còn giúp truyền
đạt thông điệp một cách rõ ràng và hiệu quả. Điều này làm cho việc làm việc với dữ
liệu trở nên dễ dàng và thu hút hơn, và giúp chúng ta hiểu rõ hơn về các mô hình và
xu hướng trong dữ liệu của mình.

1.2. Dictionaries & Pandas


Trong khóa học này, chúng ta sẽ tìm hiểu về Dictionaries, một lựa chọn thay thế cho
danh sách Python, và DataFrame của pandas, tiêu chuẩn thực tế để làm việc với dữ
liệu bảng trong Python. Bạn sẽ có cơ hội thực hành trực tiếp việc tạo và điều chỉnh
các bộ dữ liệu, và bạn sẽ học cách truy cập thông tin bạn cần từ các cấu trúc dữ liệu
này.
Dictionaries là một cấu trúc dữ liệu mạnh mẽ trong Python, cho phép chúng ta lưu trữ
dữ liệu theo cặp "khóa - giá trị". Chúng ta sẽ tìm hiểu cách tạo từ điển, thêm và xóa
các cặp khóa - giá trị, và làm việc với các phương thức và thuộc tính của từ điển.
DataFrame của pandas là một công cụ mạnh mẽ để làm việc với dữ liệu bảng. Chúng
ta sẽ học cách tạo DataFrame từ các nguồn dữ liệu khác nhau như danh sách, từ điển
và tệp CSV. Sau đó, chúng ta sẽ thực hiện các thao tác thường gặp như chọn lọc dữ
liệu, thêm hoặc xóa cột, và thực hiện các phép biến đổi dữ liệu.
 Với kiến thức về từ điển và DataFrame của pandas, bạn sẽ trở nên linh hoạt và
hiệu quả hơn trong việc làm việc với dữ liệu trong Python.
1.2.1. Định nghĩa Dictionary

Dictionary là một cấu trúc dữ liệu khác trong Python, cho phép lưu trữ dữ liệu dưới
dạng các cặp key-value. Trong ví dụ, chúng ta chuyển đổi dữ liệu về dân số sang một
dictionary, với tên của mỗi quốc gia là key và dân số tương ứng là value. Điều này
giúp chúng ta truy cập dữ liệu một cách dễ dàng và hiệu quả hơn bằng cách sử dụng
tên của quốc gia làm key để lấy dân số tương ứng.
1.2.2. Định nghĩa Pandas DataFrame:

Pandas DataFrame là một cấu trúc dữ liệu hai chiều, được sử dụng để làm việc với dữ
liệu bảng.
Nó cung cấp các phương thức mạnh mẽ để thao tác và xử lý dữ liệu tabular.
DataFrame có thể chứa các loại dữ liệu khác nhau trong các cột khác nhau, giống như
một bảng SQL hoặc một bảng tính Excel.
Pandas cũng cung cấp nhiều công cụ để thực hiện các phép biến đổi dữ liệu, như lọc,
nhóm, và tính toán thống kê.
1.2.3. Ứng Dụng:

Dictionaries thường được sử dụng để lưu trữ và truy cập dữ liệu theo dạng key-value,
đặc biệt là khi cần thực hiện các thao tác nhanh chóng với dữ liệu không có cấu trúc.
Pandas DataFrame là công cụ chính để làm việc với dữ liệu tabular trong Python. Nó
cung cấp một cách mạnh mẽ và linh hoạt để thực hiện các phân tích dữ liệu và xử lý
dữ liệu lớn.
Dictionaries và Pandas DataFrame là hai công cụ quan trọng mà mọi nhà phân tích dữ
liệu cần biết và sử dụng. Hiểu biết về cách sử dụng chúng sẽ giúp bạn thực hiện các
tác vụ phân tích dữ liệu một cách hiệu quả và linh hoạt hơn trong Python.

1.3. Logic, Control Flow and Filtering


Chúng ta sẽ tìm hiểu về Logic Boolean và cách sử dụng nó trong việc đưa ra quyết
định trong các chương trình Python. Chúng ta sẽ khám phá về các toán tử so sánh
khác nhau, cách kết hợp chúng với các toán tử Boolean, và cách sử dụng kết quả
Boolean trong các cấu trúc điều khiển. Cuối cùng, chúng ta sẽ học cách lọc dữ liệu
trong các DataFrame của Pandas bằng Logic Boolean.
1.3.1. Comparison Operators:

Các toán tử so sánh như less than, greater than, equal to, và not equal to được sử dụng
để so sánh giữa các giá trị Python và trả về kết quả là boolean (True hoặc False).
Các toán tử này hoạt động trên cả số và chuỗi, cho phép kiểm tra các điều kiện khác
nhau như xem một số có lớn hơn hoặc nhỏ hơn một giá trị khác, hoặc xem xét thứ tự
alphabet giữa các chuỗi.
Trong NumPy, các toán tử so sánh có thể được sử dụng trên các mảng và thực hiện so
sánh theo từng phần tử.
1.3.2. Boolean Operators:
Các toán tử boolean như and, or, và not được sử dụng để kết hợp các giá trị boolean
và trả về kết quả boolean tương ứng.
Toán tử and trả về True chỉ khi cả hai giá trị đều là True, trong khi or trả về True nếu
ít nhất một trong hai giá trị là True.
Toán tử not được sử dụng để phủ định giá trị boolean.
1.3.3. if:

Trong tập lệnh control.py, giả sử bạn có một biến z, bằng 4. Nếu giá trị là số chẵn,
bạn muốn in ra: "z là số chẵn". Toán tử modulo 2 sẽ trả về 0 nếu z là số chẵn. Nếu
bạn chạy đoạn mã này, Python kiểm tra xem điều kiện có đúng không. Nó đúng, vì
vậy đoạn mã tương ứng được thực thi: "z là số chẵn" được in ra.

Hình 5 Ví dụ về If

1.3.4. else:

Nếu bạn chạy nó với z bằng 5, điều kiện không đúng, vì vậy biểu thức cho câu lệnh
else được in ra. Công thức tổng quát như sau: đối với câu lệnh else, bạn không cần
chỉ định một điều kiện. Biểu thức tương ứng được thực thi nếu điều kiện của câu lệnh
if nó thuộc về không đúng.
Hình 6 Ví dụ về Esle

1.3.5. elif:

Bạn có thể nghĩ đến các trường hợp khi hành vi tùy chỉnh hơn là cần thiết. Cho rằng
bạn muốn các đầu ra khác nhau cho các số chia hết cho 2 và cho 3. Bạn có thể sử
dụng các câu lệnh elif để thực hiện điều này. Hãy xem ví dụ sau đây. Bạn có thể nói
được rằng đoạn mã này sẽ in ra gì nếu bạn chạy nó? Nếu z bằng 3, điều kiện đầu tiên
là Sai, vì vậy nó điều hướng đến điều kiện tiếp theo. Điều kiện này đúng, vì vậy câu
lệnh in tương ứng được thực thi.

Trong trường hợp z bằng 6. Cả hai điều kiện if và elif đều đúng trong trường hợp này.
Liệu có hai đầu ra in ra không? Không. Ngay khi Python gặp phải một điều kiện
đúng, nó thực thi mã tương ứng và rời khỏi cấu trúc điều khiển sau đó. Điều này có
nghĩa là điều kiện thứ hai, tương ứng với elif, không bao giờ được đạt đến, vì vậy
không có đầu ra in ra tương ứng
.
Hình 7 Ví dụ Elif

1.3.6. Filtering pandas DataFrames:

Trong Pandas, bạn có thể sử dụng các toán tử so sánh để lọc các hàng dựa trên các
điều kiện cụ thể.
Bằng cách chọn một cột từ DataFrame và thực hiện các so sánh trên cột đó, bạn có
thể tạo ra một Series chứa các giá trị boolean tương ứng với mỗi hàng.
Series boolean này có thể được sử dụng như một chỉ mục để lọc các hàng tương ứng
từ DataFrame, cho phép bạn lấy ra các bộ dữ liệu thỏa mãn các điều kiện được chỉ
định.

1.4. Loops
Chúng ta sẽ tìm hiểu về các kỹ thuật để thực thi mã Python lặp đi lặp lại. Cụ thể,
chúng ta sẽ tìm hiểu về vòng lặp while và for trong Python, hai cách tiếp cận khác
nhau nhưng đều hữu ích để thực hiện các công việc lặp lại.
1.4.1. Vòng lặp white

. Vòng lặp while khá tương tự như một câu lệnh if: nó thực thi mã bên trong nếu điều
kiện là True. Tuy nhiên, khác với câu lệnh if, vòng lặp while sẽ tiếp tục thực thi mã
này lặp đi lặp lại miễn là điều kiện là true.
Cú pháp của một vòng lặp while rất giống với câu lệnh if, như bạn có thể thấy ở đây.
Vòng lặp while không phổ biến lắm, nhưng trong một số trường hợp nó có thể rất hữu
ích. Ví dụ, giả sử bạn đang tính toán số liệu theo mô hình dựa trên dữ liệu của bạn.
Điều này thường liên quan đến việc thực hiện các bước giống nhau điều này điều kỳ
vọng làm cho lỗi giữa mô hình của bạn và dữ liệu của bạn dưới một ranh giới nào đó.
Khi bạn có thể tái phát biểu vấn đề như 'lặp lại một hành động cho đến khi một điều
kiện cụ thể được đạt được', một vòng lặp while thường là cách tiếp cận.
Giả sử rằng chúng ta bắt đầu với một lỗi là năm mươi và thuật toán phức tạp của
chúng tôi chia lỗi đó cho bốn sau mỗi lần chạy. Chúng tôi muốn tiếp tục cho đến khi
lỗi không còn cao hơn một.
Bây giờ, khi chuyển đến tập lệnh, chúng tôi bắt đầu bằng cách thêm lỗi mà chúng tôi
bắt đầu với, năm mươi. Tiếp theo, chúng tôi viết một vòng lặp while. Trong phần
điều kiện, chúng tôi viết lỗi > 1, để vòng lặp while thực thi lại miễn là lỗi vẫn còn cao
hơn 1. Bên trong mã, chúng tôi chia lỗi cho bốn và cập nhật biến lỗi. Điều này mô
phỏng thuật toán phức tạp của chúng tôi chia lỗi cho bốn sau mỗi lần chạy. Tiếp theo,
chúng tôi cũng in lỗi này. Hãy đi qua những gì xảy ra nếu bạn thực sự chạy tập lệnh
này, từng bước một.
1.4.2. Vòng lặp for

Vòng lặp for là một cách tiếp cận mạnh mẽ để lặp qua các phần tử trong một chuỗi và
thực hiện các thao tác mong muốn.
Cú pháp cơ bản của vòng lặp for là for var in seq:, trong đó var là một biến và seq là
một chuỗi. Với mỗi phần tử trong chuỗi seq, các biểu thức được thực thi.
Chúng ta đã thấy cách sử dụng vòng lặp for để lặp qua các phần tử trong một danh
sách. Ví dụ về điều này là khi chúng ta muốn in ra từng phần tử trong danh sách
chiều cao của gia đình. Thay vì sử dụng nhiều lệnh in lặp lại, chúng ta có thể sử dụng
một vòng lặp for để tự động lặp qua các phần tử và thực hiện thao tác in cho mỗi
phần tử.
Chúng ta cũng đã tìm hiểu về cách sử dụng hàm enumerate() để lặp qua các phần tử
trong danh sách và đồng thời lấy được cả chỉ số của phần tử đó. Điều này rất hữu ích
khi chúng ta cần biết cả chỉ số và giá trị của từng phần tử trong danh sách.
Cuối cùng, chúng ta đã thấy rằng vòng lặp for không chỉ hoạt động với danh sách mà
còn có thể được sử dụng để lặp qua từng ký tự trong một chuỗi. Điều này giúp chúng
ta thực hiện các thao tác phức tạp trên từng phần tử của chuỗi một cách dễ dàng.
1.4.3. Loop Data Structures
Chúng ta đã tìm hiểu về cách sử dụng vòng lặp for để duyệt qua các cặp key-value
trong dictionaries. Để làm điều này, chúng ta sử dụng phương thức items() của
dictionaries để trả về cặp key-value trong mỗi lần lặp.
Tiếp theo, chúng ta đã thấy cách sử dụng vòng lặp for để duyệt qua tất cả các phần tử
trong NumPy arrays. Chúng ta cũng đã tìm hiểu về cách sử dụng hàm nditer() của
NumPy để duyệt qua các phần tử của mảng nhiều chiều.
Sau đó, chúng ta đã thảo luận về cách sử dụng vòng lặp for để duyệt qua các hàng
trong Pandas DataFrame. Chúng ta đã biết cách sử dụng phương thức iterrows() để
trả về cặp label của hàng và dữ liệu trong hàng để mỗi lần lặp.
Cuối cùng, chúng ta đã thấy cách sử dụng hàm apply() để thực hiện các thao tác với
toàn bộ cột trong DataFrame mà không cần sử dụng vòng lặp. Điều này giúp tối ưu
hóa hiệu suất và làm cho mã trở nên dễ đọc hơn.
Tóm lại, với kiến thức về vòng lặp và cách sử dụng chúng với các cấu trúc dữ liệu
khác nhau trong Python, chúng ta có thể thực hiện các thao tác phức tạp trên dữ liệu
một cách dễ dàng và hiệu quả.

1.5. Case Study: Hacker Statistics


1.5.1. Ramdom Number

NumPy là một thư viện quan trọng trong Python dùng cho tính toán khoa học và tính
toán số học. Đặc điểm chính của NumPy là khả năng làm việc với mảng đa chiều
(ndarray), cung cấp các hàm toán học cơ bản và nâng cao, hỗ trợ indexing và slicing
trên mảng, và cho phép broadcasting các phép toán giữa các mảng có kích thước khác
nhau. NumPy được sử dụng rộng rãi trong các lĩnh vực như khoa học dữ liệu, máy
học, xử lý hình ảnh và âm thanh, mô phỏng và tính toán số. Với hiệu suất cao và một
cộng đồng lớn, NumPy là một công cụ quan trọng cho các nhu cầu tính toán số học
và khoa học trong Python.
Sử dụng hàm rand() trong module random của Numpy để sinh ramdom number trong
khoảng từ 0 đến 1.
Đặt seed để tạo ra các ramdom number có thể tái tạo được.
Sử dụng hàm randint() để mô phỏng việc tung đồng xu và xác định kết quả là "sấp"
hoặc "ngửa".
1.5.2. Random Walk

Một "random walk" là một khái niệm phổ biến trong khoa học, được áp dụng để mô
hình hóa các hiện tượng tự nhiên như đường đi của phân tử trong chất lỏng hoặc khí.
Chúng ta có thể sử dụng số ngẫu nhiên để mô phỏng các bước trong một random
walk.
Mô Phỏng Tung Đồng Xu:
Trong ví dụ về trò chơi "Heads or Tails", chúng ta sử dụng số ngẫu nhiên để quyết
định kết quả của mỗi lần tung đồng xu.
Bằng cách thêm các kết quả vào một danh sách, chúng ta có thể theo dõi số lần xuất
hiện của mỗi kết quả.

Hình 8 Ví dụ về ramdom walk

Random Walk và Tổng Số Tails:


Để chuyển đổi từ một danh sách các bước ngẫu nhiên thành một random walk, chúng
ta có thể theo dõi tổng số lần mỗi kết quả xuất hiện.
Bằng cách này, chúng ta có thể tạo ra một danh sách ghi lại sự thay đổi của số lần
xuất hiện của mỗi kết quả theo thời gian.
Hình 9 Ví dụ về tổng số tails

Hình 10 Ví dụ về tổng số tails

Tổng Kết:
Sử dụng số ngẫu nhiên và vòng lặp, chúng ta có thể mô phỏng các tình huống có tính
ngẫu nhiên như trò chơi, phân tích xác suất hoặc nghiên cứu khoa học.
Cách theo dõi và ghi lại sự thay đổi của các biến quan trọng trong quá trình mô phỏng
là điều quan trọng để hiểu và phân tích kết quả của các mô phỏng ngẫu nhiên.

2. UNIT TEST BY PYTHON

2.1. Unit testing basics


2.1.1. Ý Nghĩa của Unit Test:

Ý nghĩa của Unit Test trong lập trình là đảm bảo tính đúng đắn và ổn định của mã
nguồn thông qua việc tự động kiểm tra các phần của mã, như hàm hoặc module, để
đảm bảo chúng hoạt động như mong đợi. Cụ thể, ý nghĩa của Unit Test bao gồm:
Xác định lỗi sớm: Unit Test giúp phát hiện lỗi ngay từ giai đoạn phát triển sớm của
mã, giúp giảm thiểu thời gian và chi phí sửa lỗi sau này.
Đảm bảo tính đúng đắn: Các test case được thiết lập trong Unit Test đảm bảo rằng
các hàm và module hoạt động chính xác theo yêu cầu và kỳ vọng.
Tăng cường sự tự tin: Việc có các bộ test đầy đủ và hoàn chỉnh tạo ra sự tự tin trong
việc thay đổi mã nguồn và thêm tính năng mới, mà không lo ngại về việc làm hỏng
chức năng hiện có.
Tiết kiệm thời gian: Unit Test giúp tăng tốc quá trình kiểm thử và giảm thiểu thời
gian cần thiết cho việc kiểm tra bằng tay, đặc biệt khi mã nguồn phát triển và thay đổi
liên tục.
Tăng độ tin cậy của mã: Khi một dự án có các Unit Test đầy đủ và hiệu quả, nó tạo ra
một cảm giác tin cậy và sự an tâm cho nhóm phát triển và người sử dụng.
Vòng đời của 1 function:
Quá trình vòng đời của một hàm trong phát triển phần mềm bao gồm các bước như
sau:
Implement (Triển khai): Bắt đầu với việc triển khai hàm dựa trên yêu cầu hoặc thiết
kế.
Test (Kiểm thử): Kiểm tra hàm để đảm bảo tính đúng đắn và hoạt động chính xác.
New Feature Request (Yêu cầu tính năng mới): Có thể nhận được yêu cầu thêm tính
năng mới cho hàm.
Refactor (Tối ưu mã nguồn): Cải thiện hoặc tối ưu lại mã nguồn của hàm.
Re-test (Kiểm thử lại): Sau khi thay đổi hoặc tối ưu lại mã nguồn, cần kiểm tra lại để
đảm bảo tính đúng đắn và hoạt động như mong đợi.
Bug Discovery (Phát hiện lỗi): Có thể phát hiện ra lỗi không mong muốn trong hàm.
Bug Fix (Sửa lỗi): Sửa lỗi và kiểm tra lại để đảm bảo rằng lỗi đã được khắc phục.
Trong quá trình này, hàm cần được kiểm tra nhiều lần, đặc biệt là khi có sự thay đổi
hoặc cải thiện mã nguồn. Mỗi lần thay đổi, chúng ta cần kiểm tra lại để đảm bảo tính
ổn định và đúng đắn của hàm. Điều này có thể dẫn đến việc kiểm thử hàm hàng trăm
lần trong suốt quá trình phát triển dự án.
Hình 11 Vòng đời của funciton

Ví dụ Về Hàm row_to_list():
Hàm ví dụ được đề cập là row_to_list(), nhận vào một đối số duy nhất là một chuỗi
Python.
Chuỗi này đại diện cho một hàng dữ liệu trong tệp dữ liệu chứa thông tin về diện tích
nhà và giá thị trường của căn nhà.
Định dạng của chuỗi bao gồm diện tích nhà tính bằng feet vuông, theo sau là một tab
duy nhất, tiếp theo là giá nhà tính bằng đô la và kết thúc bằng một ký tự xuống dòng.
Nếu chuỗi tuân theo định dạng này, hàm sẽ trả về một danh sách có độ dài 2, chứa
diện tích nhà và giá nhà.
Tuy nhiên, tệp dữ liệu không sạch sẽ và một số hàng trong tệp không tuân theo định
dạng. Hàng thứ ba thiếu diện tích nhà, trong khi hàng gần cuối thiếu tab giữa diện
tích và giá.
Đối với những hàng không hợp lệ này, hàm sẽ trả về None.
Để kiểm tra hàm này, chúng ta cần thử nghiệm với tất cả các đối số đã liệt kê và kiểm
tra xem hàm trả về giá trị đúng đắn.
Hình 12 Ví dụ vè hàm Row_to_ list

Hình 13 Ví dụ vè hàm Row_to_ list 2

Hình 14 Ví dụ vè hàm Row_to_ list 3

2.1.2. Viết một bài kiểm tra đơn vị đơn giản bằng pytest

Kiểm thử trên console: Trong mỗi bước, bạn đã kiểm thử bằng cách gọi hàm
row_to_list() trên các đối số khác nhau và kiểm tra xem giá trị trả về có đúng không.
Quá trình này lặp đi lặp lại, tẻ nhạt và tốn thời gian. Trong bài học này, chúng ta sẽ
học cách viết các bài kiểm thử đơn vị và cải thiện quy trình này.

Hình 15 Kiểm thử trên console

Thư viện kiểm thử đơn vị Python: Có nhiều thư viện Python để viết bài kiểm thử đơn
vị như pytest, unittest, nosetests và doctest. Chúng ta sẽ sử dụng pytest cho khóa học
này, vì pytest có tất cả các tính năng cần thiết, dễ sử dụng nhất và là thư viện kiểm
thử phổ biến nhất trong Python.

Bước 1: Tạo một tập tin: Để bắt đầu kiểm thử đơn vị với pytest, chúng ta sẽ đầu tiên
tạo một tệp gọi là test_row_to_list.py. Khi pytest nhìn thấy một tên tệp bắt đầu bằng
"test_", nó hiểu rằng đây không phải là một tệp Python thông thường, mà là một tệp
đặc biệt chứa các bài kiểm thử đơn vị. Chúng ta phải đảm bảo tuân thủ quy ước đặt
tên này. Các tệp chứa các bài kiểm thử đơn vị còn được gọi là các module kiểm thử,
và chúng ta vừa tạo ra module kiểm thử đầu tiên của mình.

Hình 16 Ví dụ vè test_row_to_list.py

Bước 2: Nhập các thư viện: Trong module kiểm thử, chúng ta đầu tiên nhập pytest.
Sau đó, chúng ta nhập hàm cần kiểm thử.
Hình 17 Ví dụ về test_row_to_list.py 2

Bước 3: Bài kiểm thử đơn vị là các hàm Python: Một bài kiểm thử đơn vị được viết
dưới dạng một hàm Python, tên của hàm bắt đầu bằng "test_", giống như tên của
module kiểm thử. Điều này giúp pytest nhận biết rằng đó là một bài kiểm thử đơn vị
và không phải là một hàm thông thường.

Hình 18 Ví dụ về test_row_to_list.py 3

Bước 4: Kiểm tra khẳng định: Trong trường hợp này, chúng ta muốn kiểm tra xem
hàm row_to_list() có trả về danh sách đúng khi được gọi trên hàng sạch không. Biểu
thức chúng ta sử dụng là row_to_list() gọi trên đối số bằng với danh sách đúng. Nếu
hàm hoạt động, điều này sẽ đánh giá là Đúng và câu lệnh assert sẽ chạy mà không có
lỗi. Điều này sẽ làm cho bài kiểm thử đúng. Nếu hàm có lỗi, nó sẽ đánh giá là Sai,
câu lệnh assert sẽ ném ra một AssertionError và bài kiểm thử sẽ thất bại.
Hình 19 Ví dụ về test_row_to_list.py 4

Đối với dòng thứ hai trong bảng, chúng ta tạo một bài kiểm thử đơn vị gọi là
test_on_missing_area() vì đối số có dữ liệu về khu vực bị thiếu. Sau đó, chúng ta
khẳng định rằng giá trị trả về cho đối số này là None.

Hình 20 Ví dụ về test_row_to_list.py 5

Bước 5: Chạy các bài kiểm thử đơn vị bao gồm việc thực thi module kiểm thử để đảm
bảo rằng hàm row_to_list() hoạt động đúng trong suốt vòng đời của nó. Phương pháp
thông thường để chạy các bài kiểm thử này là bằng cách truy cập dòng lệnh và nhập
lệnh pytest theo sau là tên của module kiểm thử.

Hình 21 Ví dụ về test_row_to_list.py 6

2.1.3. Hiểu báo cáo kết quả kiểm tra

Chạy các kiểm thử trong IPython console tạo ra một lượng đầu ra lớn. Có quá nhiều
đầu ra nên chúng ta đã phải cắt giảm nó trong slide này. Đây được gọi là báo cáo kết
quả kiểm thử. Chúng ta sẽ chia nhỏ nó thành các phần nhỏ hơn và hiểu rõ từng phần.
Hình 22 Hiển thị báo cáo kết quả kiểm thử

Phần 1: Thông tin chung


Phần đầu tiên cung cấp thông tin về hệ điều hành, phiên bản Python, phiên bản
gói pytest, thư mục làm việc và các plugin pytest. Không có gì đáng nói về phần
này, vì vậy chúng ta sẽ tiếp tục.

Hình 23 Thông tin chung của kiểm thử

Phần 2: Kết quả kiểm thử


Tiếp theo là phần quan trọng. Đầu ra nói "collected 3 items", điều này có nghĩa là
pytest đã tìm thấy ba kiểm thử để chạy. Điều này chính xác vì module kiểm thử
test_row_to_list.py chứa ba kiểm thử đơn vị. Dòng tiếp theo chứa tên module
kiểm thử, đó là test_row_to_list.py, theo sau là các ký tự chấm, chữ cái F in hoa
và chấm. Mỗi ký tự đại diện cho kết quả của một kiểm thử đơn vị.

Hình 24 Kết quả kiểm thử


Ký tự F in hoa đại diện cho sự thất bại. Một kiểm thử đơn vị thất bại nếu một
ngoại lệ được ném khi chạy mã kiểm thử đơn vị.

Điều này thường xuyên xảy ra khi câu lệnh assert ném một AssertionError. Điều
này có nghĩa là hàm có một lỗi và chúng ta nên sửa nó.

Hình 25 Khi thêm câu lệnh assert

Một kiểm thử đơn vị cũng có thể thất bại nếu một ngoại lệ khác được ném trong
quá trình chạy mã kiểm thử đơn vị. Trong trường hợp này, việc thực thi sẽ dừng
trước khi câu lệnh assert được thực thi. Ví dụ, nếu chúng ta viết None với chữ n
thường, điều này sẽ gây ra một NameError. Vì câu lệnh assert không chạy, chúng
ta không thể kết luận gì về hàm đang được kiểm thử từ kết quả F in hoa. Trong
trường hợp này, chúng ta nên sửa lại kiểm thử đơn vị để có thể thực thi câu lệnh
assert.
Hình 26 Trường hợp nên kiểm lại

Dấu chấm có nghĩa là kiểm thử đơn vị đã qua. Điều này có nghĩa là không có
ngoại lệ nào được ném bởi câu lệnh assert hoặc bất kỳ phần nào khác của mã kiểm
thử đơn vị. Đối với module kiểm thử test_row_to_list.py, kiểm thử đầu tiên đã
qua, thứ hai thất bại và thứ ba đã qua.

Hình 27 Kiểm thử đầu tiên đã qua, thứ hai thất bại và thứ ba đã qua

Phần 3: Thông tin về các kiểm thử thất bại


Phần tiếp theo chứa thông tin chi tiết về các kiểm thử thất bại. Chúng ta có thể
thấy rằng kiểm thử đơn vị test_on_missing_area() đã thất bại. Dòng ném ngoại lệ
được đánh dấu bằng một dấu ">", ở bên trái. Trong trường hợp này, đó là câu lệnh
assert.
Hình 28 Các thông tin kiểm thử thất bại

Những dòng tiếp theo được đánh dấu bằng E in hoa ở bên trái chứa thông tin về
ngoại lệ. Trong trường hợp này, câu lệnh assert đã ném ra một AssertionError.

Hình 29 Dòng đánh dấu E là các ngoại lệ

Các dòng chứa từ "where" hiển thị bất kỳ giá trị trả về nào được tính toán khi thực
thi câu lệnh assert. Trong trường hợp này, nó cho thấy rằng giá trị trả về thực sự
của row_to_list() là một danh sách chứa một chuỗi rỗng và chuỗi "293,410". Giá
trị trả về dự kiến là, tất nhiên, None. Sự không phù hợp giữa giá trị dự kiến và
thực tế sẽ là điểm khởi đầu của chúng ta cho việc gỡ lỗi. Chúng ta sẽ phải tìm hiểu
tại sao row_to_list() trả về một danh sách thay vì None trong trường hợp này.
Hình 30 Hiển thị giá trị trở về

Phần 4: Tóm tắt kết quả kiểm thử


Dòng cuối cùng là tóm tắt kết quả kiểm thử, nói rằng "1 kiểm thử thất bại, và 2 đã
qua". Ngoài ra, chúng ta cũng biết được rằng việc kiểm thử mất 0,03 giây để chạy.
Điều đó thực sự nhanh so với thời gian chúng ta cần để kiểm thử bằng trình thông
dịch.

Hình 31 Tóm tắt kết quả kiểm thử

2.2. Intermediate unit testing


2.2.1. Nắm vững các câu khẳng định

Cấu trúc lý thuyết của một câu lệnh assert: Cho đến nay, chúng ta chỉ sử dụng một
biểu thức boolean như một đối số của câu lệnh assert.

Tham số thông báo tùy chọn: Câu lệnh assert có thể nhận một đối số thứ hai tùy chọn,
gọi là thông báo. Thông báo chỉ được in ra khi câu lệnh assert gây ra một
AssertionError và nó nên chứa thông tin về lý do tại sao AssertionError đã được gây
ra.
Hình 32 Tham số thông báo tùy chọn

Thêm một thông báo vào một bài kiểm tra đơn vị: Có thể cải thiện bài kiểm tra bằng
cách thêm một thông báo, giúp dễ dàng gỡ lỗi nếu bài kiểm tra thất bại.

Hình 33 Thêm một thông báo vào một bài kiểm tra đơn vị

Báo cáo kết quả kiểm tra với thông báo: Việc báo cáo kết quả kiểm tra với thông báo
giúp cho việc đọc và hiểu kết quả dễ dàng hơn so với kết quả tự động của pytest.
Hình 34 Báo cáo kết quả kiểm tra với thông báo

Cảnh báo về giá trị trả về kiểu float!: So sánh các giá trị float trong Python không
luôn hoạt động như mong đợi, và chúng ta cần phải sử dụng pytest.approx() để so
sánh an toàn.

Mảng NumPy chứa giá trị float: Hàm pytest.approx() cũng hoạt động cho các mảng
NumPy chứa giá trị float.

Hình 35 Cảnh báo về giá trị trả về kiểu float!

Nhiều câu lệnh assert trong một bài kiểm tra đơn vị: Một bài kiểm tra có thể chứa
nhiều hơn một câu lệnh assert, giúp kiểm tra nhiều điều kiện trong cùng một bài kiểm
tra.
Hình 36 Nhiều câu lệnh assert trong một bài kiểm tra đơn vị

2.2.2. Kiểm tra các ngoại lệ thay vì giá trị trả về

Kiểm tra ngoại lệ thay vì giá trị trả về: Cho đến nay, chúng ta đã sử dụng câu lệnh
assert để kiểm tra xem một hàm có trả về giá trị mong đợi không. Tuy nhiên, một số
hàm có thể không trả về bất cứ điều gì, mà thay vào đó là ném ra một ngoại lệ khi
được gọi với một số đối số nhất định.

Ví dụ về hàm: Lấy ví dụ về hàm split_into_training_and_testing_sets() mà bạn đã


kiểm tra trong bài tập trước đó. Hàm này trả về một hai-tuple chứa mảng huấn luyện
và mảng kiểm tra. Nó đặt 75% số hàng của mảng đối số vào mảng huấn luyện và
phần còn lại vào mảng kiểm tra.

Hình 37 Ví dụ về hàm
Kiểm tra ngoại lệ của hàm: Chúng ta sẽ học cách kiểm tra xem hàm này có ném ra
ValueError khi được gọi với một mảng một chiều không. Điều này được thực hiện
bằng cách sử dụng pytest.raises() để kiểm tra xem ngoại lệ được ném ra như mong
đợi hay không.

Hình 38 Kiểm tra ngoại lệ của hàm

Cấu trúc lý thuyết của câu lệnh with: Câu lệnh with được sử dụng để tạo một ngữ
cảnh trong đó một đối tượng được quản lý được sử dụng với một cách an toàn.

Hình 39 Cấu trúc lý thuyết của câu lệnh with

Hình 40 Cấu trúc lý thuyết của câu lệnh with 2

Kiểm tra thông điệp lỗi: Chúng ta cũng có thể kiểm tra các chi tiết của ngoại lệ được
ném ra, bao gồm kiểm tra xem thông điệp lỗi có chứa thông điệp lỗi chính xác không.
Hình 41 Kiểm tra thông điệp lỗi

2.2.3. Chức năng đã được thử nghiệm tốt

Cách kiểm tra độ dài, không phải giá trị: Vì hàm này có yếu tố ngẫu nhiên, chúng ta
kiểm tra độ dài của các mảng huấn luyện và kiểm tra thay vì các giá trị thực tế. Độ
dài của mảng huấn luyện được xác định bằng phần nguyên của 0.75 lần số hàng trong
đối số. Các hàng còn lại được đặt vào mảng kiểm tra.

Hình 42 Ví dụ cách kiểm tra độ dài, không phải giá trị


Hình 43 Cách kiểm tra độ dài, không phải giá trị

Kiểm tra đối số và giá trị trả về mong đợi: Chúng ta kiểm tra các đối số và giá trị trả
về mong đợi của hàm.

Hình 44 Kiểm tra đối số và giá trị trả về mong đợi

Số lượng đối số để kiểm tra?: Tốt nhất là lựa chọn một vài đối số từ mỗi loại đối số
xấu, đặc biệt và bình thường.
Loại I: Đối số xấu: Đây là các đối số mà hàm ném ra một ngoại lệ thay vì trả về một
giá trị.
Hình 45 Số lượng đối số để kiểm tra loại 1

Loại II: Đối số đặc biệt: Đây là các đối số mà hàm sử dụng một logic đặc biệt để sản
xuất giá trị trả về.

Hình 46 Số lượng đối số để kiểm tra loại 2

Đối số bình thường: Cuối cùng, bất kỳ điều gì không phải là đối số xấu hoặc đặc biệt
đều là đối số bình thường.

Hình 47 Đối số bình thường


2.2.4. Kiểm tra các ngoại lệ thay vì trả về giá trị

Hướng dẫn cách kiểm tra các hàm Python nâng ngoại lệ thay vì trả về giá trị, sử dụng
trình quản lý ngữ cảnh pytest.raises().
Kiểm tra ngoại lệ:
Truyền thống dùng assert kiểm tra giá tr ị trả về của hàm.
Một số hàm nâng ngoại lệ cho đầu vào không hợp lệ.
Ví dụ:
split_into_training_and_testing_sets mong đợi mảng NumPy 2 chiều.
Truyền mảng 1 chiều sẽ nâng ngoại lệ ValueError.

Hình 48 Hàm split_into_training_and_testing_sets mong đợi mảng NumPy 2 chiều

Kiểm tra ngoại lệ với pytest.raises():


1.Cấu trúc bài kiểm tra:
Tên bài kiểm tra: test_valueerror_on_one_dimensional_argument
Mảng 1 chiều làm đối số kiểm tra.
Sử dụng with để kiểm tra ngoại lệ.
2.with:
Bao bọc mã như "ngữ cảnh".
Lấy trình quản lý ngữ cảnh làm đối số.
3.Trình quản lý ngữ cảnh:
Chạy mã trước khi vào và sau khi thoát khỏi ngữ cảnh.
Giống như bảo vệ kiểm soát ra vào.
4.pytest.raises():
Lấy loại ngoại lệ mong đợi (ví dụ: ValueError).
Không chạy mã khi vào ngữ cảnh.
Bỏ qua ngoại lệ mong đợi nếu được nêu (thử nghiệm thành công).
Nâng Failed nếu không có ngoại lệ mong đợi (thử nghiệm thất bại).
Hình 49 Hàm pytest.raises():

5.Kiểm tra thông báo lỗi:

Dùng as với with để ghi lại thông tin ngoại lệ.


Kiểm tra xem ngoại lệ được ghi (exception_info) có thông báo mong đợi hay không.
Dùng assert với exception_info.match() để xác minh chuỗi con thông báo.
Kết luận:
pytest.raises() giúp đảm bảo các hàm ném ngoại lệ mong đợi cho đầu vào không hợp
lệ, giúp mã mạnh mẽ hơn.

Hình 50 Kiểm tra thông báo lỗi

Do giới hạn thời gian, không thể test tất cả các input.
Cần chọn lọc test các argument để tăng độ tin cậy cho hàm.
Có ba loại argument cần test:
1.Bad Arguments: Gây ra lỗi ngoại lệ (ví dụ: ValueError).
Ví dụ cho hàm split_into_training_and_testing_sets:
Mảng một chiều (không có hàng/cột để chia).
Mảng chỉ có một hàng (mảng training hoặc testing rỗng).
Hình 51 Bad Arguments

2.Special Arguments: Kích hoạt hành vi đặc biệt của hàm.


Giá trị biên: Phân biệt các hành vi khác nhau của hàm.
Ví dụ: Hàm báo lỗi cho một hàng, hoạt động cho nhiều hơn một. Hai hàng là giá trị
biên.
Argument có logic đặc biệt: Hàm đi chệch hướng khỏi hành vi tiêu chuẩn.
Ví dụ: Chia 4 hàng có thể dẫn đến 2-2 thay vì 3-1.

Hình 52 Special Arguments

3.Normal Arguments: Không xấu cũng không đặc biệt.


Test một vài để bao hàm các dải input khác nhau.
Ví dụ: Test hàm split_into_training_and_testing_sets
Bad Arguments: Test lỗi ngoại lệ với mảng không hợp lệ (một chiều, một hàng).
Special Arguments:
Giá trị biên: Test với hai hàng (phân biệt lỗi với hoạt động bình thường).
Logic đặc biệt: Không áp dụng trong ví dụ này (được đề cập để minh họa).
Normal Arguments: Test hai hoặc ba trong các dải input khác nhau (> giá trị biên).
Hình 53 Normal Arguments

Kết luận:
Hàm được test tốt cần bao gồm tất cả các bad argument và special argument, cùng với
một vài normal argument.
Cần điều chỉnh cách tiếp cận này cho các hàm không có bad argument hoặc special
argument.

2.2.5. Test Driven Development (TDD)

Là phương pháp viết code đảm bảo unit test được viết.
Bước đầu tiên của TDD là viết unit test trước khi viết code cho hàm.
Viết test trước giúp:
Đảm bảo test không bị trì hoãn.
Tính toán thời gian viết test vào thời gian 実装 (jiàn shí - triển khai) tổng thể.
Cần suy nghĩ về các argument (đối số) và return value (giá trị trả về) của hàm, bao
gồm cả các trường hợp bình thường, đặc biệt và lỗi.
Giúp làm rõ yêu cầu của hàm, từ đó triển khai dễ dàng hơn.
Ưu điểm:
Giúp suy nghĩ kỹ về chức năng trước khi triển khai.
Tránh trường hợp bỏ qua viết unit test.
Các bước thực hiện TDD (sẽ được áp dụng trên hàm convert_to_int):
1.Viết unit test và hoàn thiện yêu cầu hàm.

Hình 54 Viết unit test và hoàn thiện yêu cầu hàm.

2.Chạy test và quan sát lỗi (vì hàm chưa được viết).

Hình 55 Chạy test và quan sát lỗi

3.Triển khai hàm và chạy lại test.


Nếu test pass => hoàn thành.
Nếu test fail => sửa lỗi và lặp lại bước 3.
2.3. Test Organization and Execution
2.3.1. Làm thế nào để tổ chức số lượng bài kiểm tra ngày càng tăng?

Số lượng kiểm thử tăng lên đòi hỏi chúng ta cần một chiến lược để tổ chức tất cả các
kiểm thử này. Nếu không, chúng ta có nguy cơ làm cho các bài kiểm thử của chúng ta
trở nên lộn xộn, giống như một tủ quần áo.
Giả sử rằng bốn hàm mà bạn đã kiểm thử có trong cấu trúc dự án như sau:
 Thư mục cấp cao có tên là src, chứa toàn bộ mã nguồn ứng dụng.
 Bên trong có thư mục data, xử lý các chức năng tiền xử lý dữ liệu.
 Nó có một module Python gọi là preprocessing_helpers.py, chứa các hàm
row_to_list() và convert_to_int().
 Tiếp theo là thư mục features, xử lý việc trích xuất các đặc trưng từ dữ liệu đã
tiền xử lý.
 Nó có một module gọi là as_numpy.py, chứa hàm
get_data_as_numpy_array().
 Cuối cùng là thư mục models, xử lý việc huấn luyện và kiểm thử mô hình hồi
quy tuyến tính.
 Nó có một module gọi là train.py. Hiện tại, chỉ chứa một hàm
split_into_training_and_testing_sets().

Hình 56 Hàm split_into_training_and_testing_sets().

Nhà phát triển của pytest khuyến nghị chúng ta nên tạo một thư mục có tên là tests ở
cùng mức với src. Thư mục này cũng được gọi là bộ kiểm thử.
Hình 57 Bài kiểm thử test_preprocessing_helpers.py

Quy tắc chung là cho mỗi module Python my_module.py, sẽ có một bài kiểm thử
tương ứng được gọi là test_my_module.py. Ví dụ, cho module
preprocessing_helpers.py, chúng ta tạo một bài kiểm thử gọi là
test_preprocessing_helpers.py. Vì preprocessing_helpers.py thuộc gói dữ liệu, chúng
ta đặt bài kiểm thử tương ứng trong thư mục tương ứng trong thư mục tests. Bài kiểm
thử test_preprocessing_helpers.py nên chứa các bài kiểm thử cho row_to_list() và
convert_to_int().

Hình 58 Quy tắc chung là cho mỗi module Python my_module.py

2.3.2. Làm chủ việc thực hiện kiểm thử

Thư mục chính là thư mục "tests", chứa tất cả các bài kiểm thử cho dự án.
Thư mục này chứa các gói (packages) phản ánh, mỗi gói chứa một module kiểm thử.
Hình 59 Thư mục này chứa các gói (packages)

Một lớp kiểm thử chỉ là một container cho các bài kiểm thử đơn vị cho một hàm cụ
thể.
Pytest cung cấp một cách dễ dàng để thực thi tất cả các bài kiểm thử trong thư mục
"tests".
Sử dụng lệnh "pytest" trong thư mục "tests" để tự động phát hiện và thực thi tất cả các
bài kiểm thử.
Hiển thị kết quả của việc thực thi tất cả các bài kiểm thử, bao gồm số lượng bài kiểm
thử đã thực thi và kết quả của chúng.
Một tình huống điển hình để chạy lệnh kiểm thử là trên máy chủ CI sau khi có một
commit mới.

Hình 60 Máy chủ CI


Sử dụng cờ "-x" để dừng thực thi sau lần thất bại đầu tiên, giúp tiết kiệm thời gian và
tài nguyên.

Hình 61 Sử dụng cờ "-x"

Chỉ chạy một phần của bài kiểm thử bằng cách chỉ định đường dẫn tới module kiểm
thử.
Sử dụng lệnh "pytest" kèm theo đường dẫn tới module kiểm thử để chỉ thực thi các
bài kiểm thử trong module đó.
Chỉ định một lớp kiểm thử cụ thể để chỉ thực thi các bài kiểm thử trong lớp đó.

Pytest gán một ID Node cho mỗi lớp kiểm thử và bài kiểm thử đơn vị mà nó gặp
được.
Sử dụng ID Node của lớp kiểm thử để chỉ thực thi các bài kiểm thử trong lớp đó.
Sử dụng ID Node của bài kiểm thử đơn vị để chỉ thực thi bài kiểm thử đó.
Sử dụng biểu thức keyword để thực thi các bài kiểm thử.
Hình 62 Pytest gán một ID

Sử dụng biểu thức keyword để thực thi các bài kiểm thử.
Sử dụng tùy chọn "-k" để thực thi các bài kiểm thử sử dụng biểu thức từ khóa.

Hình 63 Sử dụng tùy chọn "-k"

2.3.3. Thất bại dự kiến và bỏ qua có điều kiện

Trạng thái bộ kiểm tra:


Xanh lá: Tất cả các bài kiểm tra đều thành công.
Đỏ: Một hoặc nhiều bài kiểm tra thất bại.
Thất bại dự kiến (xfail):
Sử dụng trình trang trí @pytest.mark.xfail để đánh dấu bài kiểm tra dự kiến sẽ thất
bại (ví dụ: trong TDD khi hàm chưa được triển khai).
Điều này giữ cho bộ kiểm tra màu xanh lá ngay cả khi bài kiểm tra thất bại.
Bạn có thể tùy chọn cung cấp lý do cho thất bại dự kiến.
Hình 64 Thất bại dự kiến (xfail)

Bỏ qua có điều kiện (skipif):

Sử dụng trình trang trí @pytest.mark.skipif để bỏ qua bài kiểm tra trong một số điều
kiện nhất định (ví dụ: không tương thích phiên bản Python).
Trình trang trí lấy một biểu thức boolean làm đối số.
Nếu biểu thức là True, bài kiểm tra sẽ bị bỏ qua.
Cung cấp lý do cho việc bỏ qua bài kiểm tra.

Hình 65 Bỏ qua có điều kiện (skipif)

Báo cáo lý do:


Sử dụng tùy chọn -r với pytest để xem lý do cho các bài kiểm tra bị bỏ qua và xfailed.
-rs: Hiển thị lý do bị bỏ qua trong tóm tắt.
-rx: Hiển thị lý do xfailed với chi tiết.
-rsx: Hiển thị lý do cho cả bị bỏ qua và xfailed.
Hình 66 Báo cáo lý do

Áp dụng cho các lớp kiểm tra:


Các trình trang trí xfail và skipif có thể được áp dụng cho toàn bộ các lớp kiểm tra,
không chỉ các bài kiểm tra riêng lẻ.
Điểm chính:
Các kỹ thuật này giúp quản lý các báo động giả trong TDD và xử lý các bài kiểm tra
không áp dụng trên một số hệ thống.
Chúng cải thiện độ rõ ràng của kết quả kiểm tra bằng cách chỉ ra các thất bại và bỏ
qua dự kiến với giải thích.
2.3.4. Continuous integration and code coverage

Huy hiệu trạng thái Build


Sử dụng máy chủ Tích hợp liên tục (CI) (ví dụ: Travis CI) để tự động chạy thử
nghiệm mỗi khi đẩy commit lên GitHub.
Hiển thị trạng thái thử nghiệm thành công (dự án ổn định) hoặc thất bại (dự án không
ổn định).
Tăng cường sự tin tưởng của người dùng vào độ ổn định của codebase.
Cài đặt Travis CI
1.Tạo tệp .travis.yml ở thư mục gốc của kho lưu trữ:
Xác định phiên bản Python (ví dụ: 3.6).
Xác định lệnh cài đặt (ví dụ: pip install -e . cho dự án cục bộ).
Cài đặt tập lệnh để chạy thử nghiệm (ví dụ: pytest tests).
Hình 67 Tạo tệp .travis.yml

2.Đẩy tệp .travis.yml lên GitHub.

Hình 68 Đẩy tệp .travis.yml lên GitHub.

3.1Cài đặt ứng dụng Travis CI trên hồ sơ GitHub của bạn:


Cấp quyền truy cập vào kho lưu trữ liên quan.
Đăng nhập vào Travis CI bằng tài khoản GitHub của bạn.
Xem Huy hiệu trạng thái Build
Sau khi đẩy commit, một bản dựng sẽ xuất hiện trên bảng điều khiển Travis CI.
Nhấp vào huy hiệu, chọn định dạng Markdown và dán mã vào tệp README GitHub
của bạn.
Huy hiệu độ phủ mã
Cho biết tỷ lệ phần trăm mã được thực thi bởi các thử nghiệm (số cao hơn là tốt hơn).
Sử dụng dịch vụ Codecov để tạo và tải lên báo cáo độ phủ.
Cài đặt Codecov
1.Sửa đổi .travis.yml:
Cài đặt pytest-cov và codecov để báo cáo độ phủ.
Thêm --cov=src vào lệnh thử nghiệm để tạo báo cáo độ phủ.
Thêm codecov vào cài đặt after_success để tải báo cáo lên Codecov.
Hình 69 Sửa đổi .travis.yml

2.Cài đặt ứng dụng Codecov trên hồ sơ GitHub của bạn.

2.4. Testing Models, Plots and Much More


2.4.1. Ngoài khẳng định: thiết lập và chia nhỏ

Fixture:
Chức năng chứa logic thiết lập và dọn dẹp cho bài kiểm tra.
Sử dụng decorator pytest.fixture để khai báo.
Sử dụng yield để tách phần thiết lập và dọn dẹp.
Lợi ích:
Giúp bài kiểm tra dễ đọc và dễ hiểu hơn.
Tái sử dụng logic thiết lập và dọn dẹp cho nhiều bài kiểm tra.
Ví dụ:
Fixture raw_and_clean_data_file():
Thiết lập: tạo file gốc và sạch, ghi dữ liệu vào file gốc.
Dọn dẹp: xóa cả hai file.
Hình 70 Ví dụ Fixture raw_and_clean_data_file()

Fixture tích hợp:


Truyền fixture vào fixture khác (chaining).
Ví dụ: sử dụng fixture tmpdir tạo thư mục tạm và tự động dọn dẹp.

Hình 71 Ví dụ sử dụng fixture tmpdir tạo thư mục tạm và tự động dọn dẹp

2.4.2. Mocking

Mocking là kỹ thuật thay thế các hàm phụ thuộc (dependency) bằng các bản sao giả
(mock) trong quá trình test. Mục đích là để test một hàm độc lập với các hàm phụ
thuộc của nó.
Lợi ích của Mocking
Giúp test chính xác lỗi của hàm đang kiểm tra, không phụ thuộc lỗi của hàm phụ
thuộc.
Tăng tốc độ test vì không cần thực thi các hàm phụ thuộc.
Dễ dàng kiểm tra cách thức hoạt động của hàm chính mà không bị ảnh hưởng bởi các
hàm phụ thuộc.
Cách thực hiện Mocking trong pytest:
1.Cài đặt thư viện:
pip install pytest-mock
2.Sử dụng fixture mocker:
Python
@pytest.fixture
def mocker(pytestconfig):
return mocker.Mocker(config=pytestconfig)
3.Sử dụng phương thức patch():
Python
@pytest.mark.parametrize("input_data", ...)
def test_my_function(mocker, input_data):
# Tạo mock cho hàm phụ thuộc
mock_dependency = mocker.patch("module.dependency_function")
# Thiết lập hành vi mong đợi cho mock
mock_dependency.return_value = expected_return_value
# Gọi hàm chính
my_function(input_data)
# Kiểm tra hành vi của mock
mock_dependency.assert_called_with(expected_argument)
Ví dụ:
Giả sử ta muốn test hàm my_function sử dụng hàm phụ thuộc dependency_function.
def my_function(input_data):
result = dependency_function(input_data)
# ...
def dependency_function(input_data):
# ...
Ta có thể test hàm my_function như sau:
@pytest.mark.parametrize("input_data", ...)
def test_my_function(mocker, input_data):
# Tạo mock cho `dependency_function`
mock_dependency = mocker.patch("module.dependency_function")
# Thiết lập hành vi mong đợi cho mock
mock_dependency.return_value = expected_return_value
# Gọi `my_function`
my_function(input_data)
# Kiểm tra hành vi của mock
mock_dependency.assert_called_with(expected_argument)
2.4.3. Testing models

1.@pytest.mark.parametrize("input_data", ...):
Cho phép pytest chạy test nhiều lần với các giá trị khác nhau cho tham số input_data.
"..." là placeholder cho các giá trị cụ thể sẽ được cung cấp sau.
2. def test_my_function(mocker, input_data)::
Định nghĩa hàm test.
Hai tham số:
mocker: Cung cấp bởi pytest-mock, giúp tạo mock object.
input_data: Nhận các giá trị khác nhau trong mỗi lần chạy test.
3. mock_dependency = mocker.patch("module.dependency_function"):
Tạo mock object cho dependency_function bằng mocker.
Tham số là tên đầy đủ của hàm muốn mock: "module.dependency_function".
4. mock_dependency.return_value = expected_return_value:
Thiết lập giá trị trả về mong muốn cho mock object.
Khi my_function gọi dependency_function, nó sẽ nhận expected_return_value thay vì
thực thi.
5. my_function(input_data):
Gọi hàm cần test (my_function) với giá trị hiện tại của input_data.
6. mock_dependency.assert_called_with(expected_argument):
Kiểm tra mock object dependency_function được gọi với đúng tham số.
Đảm bảo my_function tương tác với mock object theo dự định.
Kết luận:
Đoạn mã này minh họa cách test hàm (my_function) phụ thuộc vào hàm khác
(dependency_function) bằng cách sử dụng mock object để cô lập hành vi và đảm bảo
hoạt động chính xác với các đầu vào khác nhau.
2.4.4. Testing plots

Vấn đề:
Kiểm thử từng thuộc tính của object trả về từ hàm tạo plot (matplotlib.figure.Figure)
rất tốn thời gian.
Giải pháp:
Tạo baseline image (một lần):
Chọn bộ tham số mẫu cho hàm tạo plot.
Gọi hàm tạo plot với tham số mẫu.
Chuyển object trả về thành ảnh PNG.
Kiểm tra thủ công ảnh này và lưu trữ nếu đạt yêu cầu (baseline image).
Kiểm thử:
Gọi hàm tạo plot với tham số mẫu.
Chuyển object trả về thành ảnh PNG.
Sử dụng thư viện pytest-mpl so sánh ảnh này với baseline image.
Các bước thực hiện:

1. Cài đặt pytest-mpl: pip install pytest-mpl


2. Viết test case:

Sử dụng pytest.mark.mpl_image_compare để so sánh ảnh.


3. Tạo baseline image:

Chạy test với --mpl-generate-path <đường dẫn thư mục baseline>


4. Kiểm tra baseline image thủ công.
5. Chạy test bình thường: pytest –mpl
Hình 72 Chạy test bình thường: pytest –mpl

Lợi ích:
Kiểm tra nhanh chóng sự thay đổi về mặt hiển thị của plot.
Dễ dàng debug khi test thất bại qua các ảnh được lưu trữ.
CHƯƠNG 3: TỔNG KẾT

1. Khó khăn và thuận lợi

1.1 Khó khăn

 Thiếu kinh nghiệm thực tế: Là thực tập sinh, em thiếu kinh nghiệm thực tế
trong việc test phần mềm, dẫn đến khó khăn trong việc áp dụng kiến thức lý
thuyết vào thực tế.
 Thiếu kiến thức chuyên môn: Do mới bắt đầu, em có thể thiếu kiến thức
chuyên môn về các kỹ thuật test và quy trình test phần mềm.
 Áp lực công việc: Việc test phần mềm có thể đòi hỏi em phải làm việc với
cường độ cao và đáp ứng deadline gấp rút.
 Khó khăn trong giao tiếp: Do thiếu kinh nghiệm làm việc, em có thể gặp khó
khăn trong việc giao tiếp với các thành viên khác trong team.

1.2 Thuận lợi

 Cơ hội học hỏi: Làm thực tập sinh tester cho phép em học hỏi nhiều kiến thức
và kỹ năng mới về test phần mềm.
 Cơ hội phát triển: Tham gia vào môi trường làm việc thực tế giúp em rèn luyện
kỹ năng giải quyết vấn đề, tư duy logic và kỹ năng giao tiếp.
 Cơ hội tạo dựng mạng lưới quan hệ: Em có cơ hội gặp gỡ và kết nối với các
chuyên gia trong lĩnh vực test phần mềm.

2. Bài học kinh nghiệm cho bản thân

2.1 Về kiến thức

Em đã được học về các kiến thức nền tảng về lập trình, quy trình phát triển phần
mềm, các kỹ thuật test và công cụ test. Kiến thức này giúp em hiểu rõ hơn về cách
thức hoạt động của phần mềm và vai trò của tester trong quá trình phát triển phần
mềm. Em đã được học về các kỹ thuật test chức năng, test phi chức năng, test tự động
và test hiệu suất. Kiến thức này giúp em có thể áp dụng vào thực tế để thực hiện các
công việc test phần mềm một cách hiệu quả.
2.2 Về kỹ năng

Em đã được rèn luyện kỹ năng giao tiếp thông qua việc trao đổi với các thành viên
trong team, viết báo cáo test và thuyết trình kết quả test. Kỹ năng này giúp em có thể
truyền đạt thông tin một cách hiệu quả và thuyết phục. Em đã được học cách phân
tích vấn đề, tìm kiếm nguyên nhân và đề xuất giải pháp cho các lỗi phát hiện được.
Em đã được rèn luyện kỹ năng làm việc nhóm thông qua việc tham gia vào các dự án
test cùng với các thành viên khác trong team.
Kỹ năng này giúp em có thể phối hợp hiệu quả với các thành viên khác để hoàn thành
mục tiêu chung.

2.3 Về thái độ - ý thức - tác phong

Em đã thấu hiểu tầm quan trọng của thái độ, ý thức và tác phong trong môi
trường làm việc. Việc làm việc trong môi trường đa dạng yêu cầu em thể hiện thái độ
cởi mở, tôn trọng ý kiến của người khác và biết lắng nghe. Tính trách nhiệm và tận
tâm trong công việc cũng là yếu tố quyết định sự thành công. Việc thể hiện tác phong
chuyên nghiệp, giao tiếp rõ ràng và hiểu rõ tâm tư của đồng đội giúp xây dựng mối
quan hệ tốt trong môi trường làm việc.

3. Tổng kết

Hơn 2 tháng thực tập tại công ty là một hành trình đầy ý nghĩa, khơi mở những bài
học quý giá cho bản thân em. Không chỉ thu thập kiến thức và kỹ năng chuyên môn,
em còn được tôi luyện về thái độ và ý thức trong công việc - những yếu tố then chốt
cho sự phát triển lâu dài.
Em xin gửi lời cảm ơn chân thành đến ban lãnh đạo công ty, các anh chị trong team
đã tạo điều kiện cho em học hỏi và phát triển. Em cũng cảm ơn gia đình và bạn bè đã
luôn ủng hộ em trên con đường này.
PHỤ LỤC

Hình 73 Chứng chỉ Intermediate

Hình 74 Chứng chỉ Unit Testing for Data Science in Python


TÀI LIỆU THAM KHẢO
[1] "DataCamp," [Online]. Available:
https://app.datacamp.com/learn/courses/intermediate-python.
[2] "DataCamp," [Online]. Available: https://app.datacamp.com/learn/courses/unit-
testing-for-data-science-in-python-archived.

You might also like