การทดสอบขั้นตอนกระบวนการด้วยการยืนยันเงื่อนไข
เพิ่มการตรวจสอบจำนวนแถว การยืนยันค่า null และตัวตรวจสอบคอลัมน์ที่คาดไว้ในแต่ละขั้น เพื่อให้พบข้อผิดพลาดได้ทันที
การทดสอบขั้นตอนกระบวนการด้วยการยืนยันเงื่อนไข เป็นบทเรียน Pandas & NumPy Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Pandas & NumPy Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องทดสอบขั้นตอนของ Pipeline
pipeline ข้อมูลที่ทำงานโดยไม่มีข้อผิดพลาดก็ยังอาจสร้าง ผลลัพธ์ที่ผิดโดยไม่แสดงสัญญาณเตือน ได้ เช่น แถวถูกลบด้วยตัวกรองที่ไม่ถูกต้อง คอลัมน์ถูกคูณด้วยตัวคูณที่ผิด หรือการรวมข้อมูลทำให้เกิดแถวซ้ำเพราะคีย์เชื่อมโยงไม่เป็นค่าไม่ซ้ำ วิธีเดียวที่จะตรวจจับความล้มเหลวที่ไม่แสดงสัญญาณเหล่านี้คือฝัง assertion เพื่อตรวจสอบคุณสมบัติที่คาดหวังของข้อมูลในแต่ละขั้นตอนของ pipeline assertion จะเปลี่ยนข้อผิดพลาดทางตรรกะให้เป็นข้อผิดพลาดที่แสดงออกอย่างชัดเจนและมองเห็นได้ทันที
import pandas as pd
import numpy as np
# A transform that looks correct but has a bug:
def compute_revenue_buggy(df):
# BUG: unit_price should be multiplied, not added
df['revenue'] = df['quantity'] + df['unit_price']
return df
# Without assertions, this runs silently with wrong numbers.การตรวจสอบจำนวนแถว
หลังขั้นตอนการกรองทุกครั้ง ให้ตรวจสอบว่าจำนวนแถวที่ได้อยู่ในช่วงที่คาดไว้ หากมีแถวน้อยเกินไป แสดงว่าตัวกรองเข้มงวดเกินไป หากมีแถวมากเกินไป แสดงว่าการเชื่อมโยงทำให้ระเบียนซ้ำ ให้แสดงช่วงที่คาดไว้เป็นสัดส่วนของข้อมูลเข้า ตัวอย่างเช่น ขั้นตอนการลบค่าว่างไม่ควรลบแถวเกิน 30 % ในข้อมูลที่มีคุณภาพตามปกติ ตัวป้องกันนี้ช่วยตรวจจับการเปลี่ยนแปลงด้านคุณภาพข้อมูลที่ไม่คาดคิดในแหล่งข้อมูลต้นทาง
def drop_nulls_guarded(df, required_cols, max_drop_fraction=0.3):
before = len(df)
result = df.dropna(subset=required_cols)
after = len(result)
drop_fraction = (before - after) / before
assert drop_fraction <= max_drop_fraction, \
f'dropna removed {drop_fraction:.1%} of rows (limit {max_drop_fraction:.1%})'
return resultการตรวจสอบการมีอยู่ของคอลัมน์
ตรวจสอบว่าคอลัมน์ผลลัพธ์ที่คาดไว้ทั้งหมดมีอยู่หลังฟังก์ชันการแปลงข้อมูลทุกครั้ง หากขั้นตอนการเปลี่ยนชื่อใช้คีย์ผิดโดยไม่ตั้งใจ คอลัมน์ที่ได้จะหายไป และข้อผิดพลาดจะปรากฏขึ้นในภายหลังมากเมื่อขั้นตอนอื่นพยายามใช้งาน assertion ที่วางทันทีหลังการแปลงข้อมูลจะตรวจพบปัญหาตั้งแต่ต้นทาง แทนที่จะรออีกสามขั้นตอนแล้วพบ KeyError ที่ทำให้สับสน
def compute_revenue(df):
df = df.assign(revenue=lambda d: d['quantity'] * d['unit_price'])
# Guard: check that the new column exists and is non-null
assert 'revenue' in df.columns, 'revenue column not created'
assert df['revenue'].notna().all(), 'revenue has unexpected NaNs'
return dfAssertion ของช่วงค่า
หลังคำนวณคอลัมน์รายได้ ให้ตรวจสอบว่าค่าทั้งหมดไม่ติดลบ หลังแยกวิเคราะห์วันที่ ให้ตรวจสอบว่าวันที่อยู่ในช่วงปีที่คาดไว้ หลังเข้ารหัสหมวดหมู่ ให้ตรวจสอบว่าไม่มีรหัสที่ไม่คาดคิดปรากฏขึ้น assertion แต่ละรายการคือข้อตกลงข้อมูลที่บันทึกพฤติกรรมที่คาดหวังไว้และตรวจจับการละเมิดได้ตั้งแต่เนิ่น ๆ ให้เขียนเป็น assertion แทนคำสั่งพิมพ์ เพื่อให้เกิดข้อผิดพลาดในการทำงานของ pipeline แบบอัตโนมัติ
def validate_computed_columns(df):
assert (df['revenue'] >= 0).all(), \
f'Negative revenue: {df[df["revenue"] < 0]["revenue"].head().tolist()}'
assert (df['quantity'] > 0).all(), \
'Non-positive quantity found'
assert df['revenue'].between(0, 1_000_000).all(), \
'Revenue out of plausible range'
print('Value range checks passed.')ตัวป้องกันข้อมูลซ้ำหลังการรวม
ข้อผิดพลาดของข้อมูลที่พบได้บ่อยคือการรวมแบบหลายต่อหลายที่ทำให้จำนวนแถวเพิ่มขึ้นโดยไม่ตั้งใจ หลัง pd.merge() ทุกครั้ง ให้ตรวจสอบว่าจำนวนแถวเป็นไปตามที่คาดไว้ โดยทั่วไปคือไม่เกินจำนวนแถวของ DataFrame ฝั่งซ้ายสำหรับการรวมแบบ left นอกจากนี้ ให้ตรวจสอบว่าคอลัมน์คีย์มีค่าไม่ซ้ำหากควรเป็นเช่นนั้น เพื่อให้ตรวจพบการเชื่อมโยงแบบไขว้ที่เกิดขึ้นโดยไม่ตั้งใจได้ทันที
def safe_merge(left, right, on, how='left'):
before = len(left)
result = left.merge(right, on=on, how=how)
after = len(result)
if how == 'left':
assert after == before, \
f'Left join increased rows from {before} to {after} — check key uniqueness in right df'
return resultการตรวจสอบค่าว่างหลังขั้นตอนสำคัญ
คอลัมน์บางรายการต้องไม่มีค่าว่างไม่ว่า pipeline จะอยู่ในขั้นตอนใด ให้ตรวจสอบ df['key_col'].notna().all() หลังทุกขั้นตอนที่อาจทำให้เกิดค่าว่างโดยไม่ตั้งใจ เช่น การรวมข้อมูลที่จับคู่บางแถวไม่สำเร็จ ซึ่งทำให้คอลัมน์ที่เชื่อมเข้ามามีค่า NaN หรือการเรียก map() ที่คืนค่า NaN สำหรับค่าที่ไม่มีการแมป ให้การตรวจสอบเหล่านี้เป็นสองบรรทัดสุดท้ายของฟังก์ชันการแปลงข้อมูลทุกฟังก์ชันที่ใช้งานคอลัมน์เหล่านั้น
NOT_NULL_AFTER_TRANSFORM = ['order_id', 'revenue', 'category']
def post_transform_checks(df):
for col in NOT_NULL_AFTER_TRANSFORM:
null_count = df[col].isna().sum()
assert null_count == 0, \
f'{col}: {null_count} unexpected NaN values after transform'
print('Null checks passed.')
return dfสร้างชุดการทดสอบสำหรับขั้นตอนของ Pipeline
เขียนการทดสอบหน่วยสำหรับฟังก์ชัน pipeline แต่ละฟังก์ชัน โดยใช้ DataFrame ขนาดเล็กที่สร้างขึ้นเองเพื่อแยกตรรกะที่ต้องการทดสอบ การทดสอบแต่ละรายการควรทำดังนี้: เตรียมข้อมูลเข้าขั้นต่ำ เรียกใช้ฟังก์ชัน และตรวจสอบคุณสมบัติของผลลัพธ์ การใช้ assert ที่มีอยู่ใน Python ก็เพียงพอสำหรับ pipeline แบบง่าย ส่วนโครงการขนาดใหญ่ให้ใช้ pytest เพื่อเรียกใช้การทดสอบทั้งหมดโดยอัตโนมัติก่อนนำไปใช้งาน
def test_compute_revenue():
test_df = pd.DataFrame({
'quantity': [2, 3],
'unit_price': [10.0, 5.0]
})
result = compute_revenue(test_df)
assert 'revenue' in result.columns
assert result['revenue'].tolist() == [20.0, 15.0]
assert result['revenue'].dtype == float
print('test_compute_revenue PASSED')
test_compute_revenue()การทดสอบกรณีขอบ
การทดสอบที่ดีไม่ได้ครอบคลุมเฉพาะกรณีปกติเท่านั้น แต่ยังครอบคลุมกรณีขอบด้วย ได้แก่ ข้อมูลเข้าที่เป็นค่าว่างทั้งหมด DataFrame ว่าง DataFrame ที่มีแถวเดียว และคอลัมน์ที่มีค่าสุดขั้ว DataFrame ว่างควรคืนค่าเป็น DataFrame ว่าง ไม่ใช่ข้อผิดพลาด DataFrame ที่มีแถวเดียวควรคำนวณผลลัพธ์ได้ถูกต้อง ให้ทดสอบกรณีเหล่านี้โดยเฉพาะ เพื่อให้มั่นใจว่าเมื่อข้อมูลผิดปกติเข้ามาในระบบจริง pipeline จะจัดการได้อย่างเหมาะสม
def test_empty_df():
empty = pd.DataFrame({'quantity': [], 'unit_price': []})
result = compute_revenue(empty)
assert len(result) == 0, 'Empty input should produce empty output'
assert 'revenue' in result.columns, 'Revenue column should still be created'
print('test_empty_df PASSED')
def test_single_row():
single = pd.DataFrame({'quantity': [1], 'unit_price': [99.0]})
result = compute_revenue(single)
assert result['revenue'].iloc[0] == 99.0
print('test_single_row PASSED')
test_empty_df()
test_single_row()การทดสอบการทำงานร่วมกัน: Pipeline เต็มรูปแบบกับข้อมูลตัวอย่าง
นอกเหนือจากการทดสอบหน่วยของฟังก์ชันแต่ละรายการแล้ว ให้เขียน การทดสอบการทำงานร่วมกัน ที่เรียกใช้ pipeline ครบถ้วนกับตัวอย่างข้อมูลจริงขนาดเล็กที่เป็นตัวแทนข้อมูลจริง ตรวจสอบว่าผลลัพธ์มีจำนวนคอลัมน์ตามที่คาดไว้ คอลัมน์คีย์มีค่าไม่ซ้ำ และรายได้รวมอยู่ในช่วงที่สมเหตุสมผล การตรวจสอบตั้งแต่ต้นจนจบนี้ช่วยตรวจจับข้อผิดพลาดจากการทำงานร่วมกันระหว่างขั้นตอนต่าง ๆ ซึ่งการทดสอบหน่วยไม่สามารถเปิดเผยได้
def integration_test(config):
raw = extract(config)
clean = transform(raw, config)
assert set(config['required_cols']).issubset(set(clean.columns))
assert clean['order_id'].is_unique
assert (clean['revenue'] >= 0).all()
assert len(clean) > 0
print(f'Integration test PASSED. Output: {clean.shape}')
integration_test(CONFIG)การทดสอบอย่างต่อเนื่องด้วย pytest
เมื่อ pipeline มีขนาดใหญ่ขึ้น ให้รวบรวมการทดสอบทั้งหมดไว้ในไดเรกทอรี tests/ และเรียกใช้ด้วย pytest จากบรรทัดคำสั่ง ไฟล์ conftest.py สามารถสร้างชุดข้อมูลทดสอบร่วม เช่น DataFrames ตัวอย่างได้ ให้ผนวก pytest เข้ากับ pipeline CI/CD เพื่อให้การเปลี่ยนแปลงโค้ดทุกครั้งเรียกใช้การทดสอบทั้งหมดโดยอัตโนมัติก่อนนำไปใช้งาน หากการทดสอบล้มเหลว ระบบจะระงับการนำไปใช้งาน เพื่อป้องกันไม่ให้โค้ดที่มีปัญหาไปถึงระบบจริง
# tests/test_transform.py — example structure
# import pytest, pandas as pd
# from pipeline.transform import compute_revenue, drop_nulls
# @pytest.fixture
# def sample_df():
# return pd.DataFrame({'quantity': [2, 3], 'unit_price': [10.0, 5.0]})
# def test_revenue(sample_df):
# result = compute_revenue(sample_df)
# assert result['revenue'].tolist() == [20.0, 15.0]
print('Run: pytest tests/ -v to execute all pipeline tests')Assertion ในฐานะเอกสารที่มีชีวิต
assertion แต่ละรายการใน pipeline เป็นทั้งตัวป้องกันและส่วนหนึ่งของเอกสาร กล่าวคือระบุในรูปแบบที่เครื่องอ่านได้ว่าข้อมูลต้องมีลักษณะอย่างไร ณ จุดนั้น เมื่อนักวิเคราะห์คนใหม่เข้าร่วมโครงการและอ่านโค้ด pipeline assertion จะบอกข้อตกลงข้อมูลให้ทราบโดยไม่ต้องอาศัยเอกสารข้อกำหนดแยกต่างหาก ให้ปฏิบัติต่อ assertion ทุกตัวเหมือนความคิดเห็นในโค้ด โดยเขียนข้อความให้ละเอียดพอที่จะเข้าใจกฎทางธุรกิจที่ assertion นั้นบังคับใช้
# These assertions document business rules as code:
assert (df['order_date'] >= pd.Timestamp('2020-01-01')).all(), \
'Company was founded 2020-01-01; no orders can predate this'
assert df['region'].isin({'North', 'South', 'East', 'West', 'Central'}).all(), \
'Only 5 sales regions are valid; new regions require config update'
print('Business rules verified as assertions.')ตรวจสอบอย่างรวดเร็ว
ทดสอบความเข้าใจแนวคิดด้านการวิเคราะห์ข้อมูลจากบทเรียนนี้
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้เกี่ยวกับ: การฝังการตรวจสอบจำนวนแถว การมีอยู่ของคอลัมน์ ช่วงค่า และค่าว่างไว้ใน pipeline ในรูปแบบ assertion การเขียนการทดสอบหน่วยสำหรับฟังก์ชันการแปลงข้อมูลแต่ละรายการ โดยครอบคลุมกรณีขอบ และ การเรียกใช้การทดสอบการทำงานร่วมกัน รวมถึงการมอง assertion เป็นเอกสารข้อตกลงข้อมูลที่มีชีวิต บทถัดไป เราจะสำรวจการจัดตารางเวลาและการบันทึกการทำงานของ pipeline เพื่อให้ทำงานอัตโนมัติทุกวัน
เรียนรู้ Python ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 30
- บทเรียน
- 120
คำถามที่พบบ่อย
บทเรียน “การทดสอบขั้นตอนกระบวนการด้วยการยืนยันเงื่อนไข” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การทดสอบขั้นตอนกระบวนการด้วยการยืนยันเงื่อนไข” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Pandas & NumPy Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การทดสอบขั้นตอนกระบวนการด้วยการยืนยันเงื่อนไข”
เพิ่มการตรวจสอบจำนวนแถว การยืนยันค่า null และตัวตรวจสอบคอลัมน์ที่คาดไว้ในแต่ละขั้น เพื่อให้พบข้อผิดพลาดได้ทันที คุณปฏิบัติ Pandas & NumPy Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Pandas & NumPy Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Pandas & NumPy Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การทดสอบขั้นตอนกระบวนการด้วยการยืนยันเงื่อนไข” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Pandas & NumPy Academy นี้ได้ไหม
ได้ บทเรียน Pandas & NumPy Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การจัดโครงสร้างขั้นตอนการแปลงเป็นฟังก์ชัน
- การกำหนดพารามิเตอร์ให้กระบวนการด้วยพจนานุกรมการตั้งค่า
- การทดสอบขั้นตอนกระบวนการด้วยการยืนยันเงื่อนไข
- การจัดเวลาและบันทึกการทำงานของกระบวนการ