کنترل کیفیت کد
در این فصل قصد داریم قوانین جدید audit و tidy را به Makefile خود اضافه کنیم تا به صورت خودکار کد پروژه را بررسی، تست و مرتب کنیم. داشتن قوانینی مانند اینها مفید است، زیرا میتوانید قبل از commit تغییرات به سیستم کنترل نسخه یا ساختن هر binary، به طور منظم آنها را اجرا کنید.
قانون audit هیچ تغییری در کد پروژه ایجاد نمیکند، بلکه صرفاً مشکلات را گزارش میدهد. به طور خاص این کارها را انجام میدهد:
استفاده از دستور
go mod tidy -diffبرای بررسی اینکه آیا فایلهایgo.modوgo.sumقدیمی شدهاند و نیاز به اصلاح دارند (که میتوانید با اجرایgo mod tidyآنها را تعمیر کنید).استفاده از دستور
go mod verifyبرای بررسی اینکه dependencyهای موجود در کامپیوتر شما (واقع در module cache در مسیر$GOPATH/pkg/mod) از زمان دانلود تغییر نکردهاند و با hashهای رمزنگاری در فایلgo.sumشما مطابقت دارند. اجرای این دستور کمک میکند تا مطمئن شوید dependencyهایی که استفاده میکنید دقیقاً همانهایی هستند که انتظار دارید.استفاده از دستور
go vet ./...برای بررسی تمام فایلهای.goدر دایرکتوری پروژه. ابزارgo vetانواع مختلفی از تحلیلگرها را اجرا میکند که تحلیل ایستای کد شما را انجام میدهند و در مورد چیزهایی که ممکن است اشتباه باشند اما توسط کامپایلر تشخیص داده نمیشوند به شما هشدار میدهند — مانند کد غیرقابل دسترس، تخصیصهای غیرضروری و build tagهای نادرست.استفاده از ابزار third-party
staticcheckبرای انجام بررسیهای تحلیل ایستای اضافی.استفاده از دستور
go test -race -vet=off ./...برای اجرای تمام تستها در دایرکتوری پروژه. به طور پیشفرض،go testقبل از اجرای تستها، مجموعه کوچکی از بررسیهایgo vetرا به صورت خودکار اجرا میکند، بنابراین برای جلوگیری از تکرار، از پرچم-vet=offاستفاده میکنیم تا این قابلیت را غیرفعال کنیم. پرچم-racerace detector زبان Go را فعال میکند که میتواند در حین اجرای تستها برخی از انواع race conditionها را شناسایی کند.
در مقابل، قانون tidy واقعاً تغییراتی در کد پروژه ایجاد میکند. این کارها را انجام میدهد:
استفاده از دستور
go mod tidyبرای حذف dependencyهای استفادهنشده از فایلهایgo.modوgo.sumو اضافه کردن dependencyهای موجود.استفاده از دستور
go fmt ./...برای فرمتبندی تمام فایلهای.goدر دایرکتوری پروژه، طبق استاندارد Go. این کار فایلها را ‘در جای خود’ بازنویسی میکند و نام فایلهای تغییر یافته را نمایش میدهد.
اگر میخواهید همراه ما پیش بروید، از دستور go get -tool برای اضافه کردن آخرین نسخه staticcheck به عنوان یک tool dependency در فایل go.mod خود استفاده کنید. به این صورت:
$ go get -tool honnef.co/go/tools/cmd/staticcheck@latest go: downloading honnef.co/go/tools v0.6.0 go: downloading golang.org/x/tools v0.30.0 go: downloading github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c go: downloading golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 go: downloading golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa go: downloading golang.org/x/mod v0.23.0 go: downloading golang.org/x/sync v0.11.0 go: added github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c go: added golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 go: upgraded golang.org/x/mod v0.17.0 => v0.23.0 go: upgraded golang.org/x/sync v0.10.0 => v0.11.0 go: upgraded golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d => v0.30.0 go: added honnef.co/go/tools v0.6.0
پس از اتمام، اکنون باید بتوانید staticcheck را با استفاده از دستور go tool اجرا کنید، به این صورت:
$ go tool staticcheck --version staticcheck 2025.1 (0.6.0) $ go tool staticcheck ./...
اکنون بیایید قوانین جدید tidy و audit را در makefile خود ایجاد کنیم. همچنین چند بلوک کامنت برای کمک به سازماندهی و روشن کردن هدف قوانین مختلف makefile اضافه میکنیم، به این صورت:
include .envrc # ==================================================================================== # # HELPERS # ==================================================================================== # ## help: print this help message .PHONY: help help: @echo 'Usage:' @sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /' .PHONY: confirm confirm: @echo -n 'Are you sure? [y/N] ' && read ans && [ $${ans:-N} = y ] # ==================================================================================== # # DEVELOPMENT # ==================================================================================== # ## run/api: run the cmd/api application .PHONY: run/api run/api: go run ./cmd/api -db-dsn=${GREENLIGHT_DB_DSN} ## db/psql: connect to the database using psql .PHONY: db/psql db/psql: psql ${GREENLIGHT_DB_DSN} ## db/migrations/new name=$1: create a new database migration .PHONY: db/migrations/new db/migrations/new: @echo 'Creating migration files for ${name}...' migrate create -seq -ext=.sql -dir=./migrations ${name} ## db/migrations/up: apply all up database migrations .PHONY: db/migrations/up db/migrations/up: confirm @echo 'Running up migrations...' migrate -path ./migrations -database ${GREENLIGHT_DB_DSN} up # ==================================================================================== # # QUALITY CONTROL # ==================================================================================== # ## tidy: tidy module dependencies and format all .go files .PHONY: tidy tidy: @echo 'Tidying module dependencies...' go mod tidy @echo 'Formatting .go files...' go fmt ./... ## audit: run quality control checks .PHONY: audit audit: @echo 'Checking module dependencies...' go mod tidy -diff go mod verify @echo 'Vetting code...' go vet ./... go tool staticcheck ./... @echo 'Running tests...' go test -race -vet=off ./...
اکنون که این کار انجام شد، تنها کاری که باید انجام دهید تایپ make tidy و make audit برای اجرای این بررسیهاست. بیایید امتحان کنیم.
اگر دقیقاً همراه ما پیش رفته باشید، خروجی باید بسیار شبیه به این باشد:
$ make tidy Tidying module dependencies... go mod tidy go: downloading github.com/google/go-cmp v0.6.0 Formatting .go files... go fmt ./... $ make audit Checking module dependencies... go mod tidy -diff go mod verify all modules verified Vetting code... go vet ./... go tool staticcheck ./... Running tests... go test -race -vet=off ./... ? greenlight.alexedwards.net/cmd/api [no test files] ? greenlight.alexedwards.net/cmd/examples/cors/preflight [no test files] ? greenlight.alexedwards.net/cmd/examples/cors/simple [no test files] ? greenlight.alexedwards.net/internal/data [no test files] ? greenlight.alexedwards.net/internal/jsonlog [no test files] ? greenlight.alexedwards.net/internal/mailer [no test files] ? greenlight.alexedwards.net/internal/validator [no test files]
این خیلی خوب است. دستور make tidy باعث شد چند پکیج اضافی دانلود شوند، اما به جز آن، تمام بررسیها بدون هیچ مشکلی با موفقیت تکمیل شدند.
اطلاعات اضافی
تستنویسی
ما موضوع تستنویسی را در کتاب اول Let's Go به طور مفصل پوشش دادیم و همان اصول اینجا نیز صدق میکنند. در صورت تمایل، میتوانید بخش تستنویسی کتاب Let's Go را مرور کنید و برخی از همان الگوها را در API خود پیادهسازی کنید. به عنوان مثال، ممکن است بخواهید این کارها را امتحان کنید:
ایجاد یک تست end-to-end برای endpoint
GET /v1/healthcheckبرای تأیید اینکه هدرها و بدنه پاسخ مطابق انتظار شماست.ایجاد یک تست unit برای middleware
rateLimit()برای تأیید اینکه پس از تعداد معینی درخواست، پاسخ429 Too Many Requestsارسال میکند.ایجاد یک تست یکپارچگی end-to-end، با استفاده از یک نمونه دیتابیس تست، که تأیید کند middlewareهای
authenticate()وrequirePermission()به درستی با هم کار میکنند تا دسترسی به endpointهای خاص را مجاز یا غیرمجاز کنند.