منابع پروژه آزمایش واحد و خطوط لوله CI/CD؟

رویکرد غیر متعارف ، اینطور نیست؟ چه کسی وقت دارد تست واحد خطوط لوله؟ خوب ، اگر تا به حال یک استقرار به صورت جانبی رفته اید زیرا شخصی فراموش کرده است که یک فایل خط لوله را به روز کند ، می فهمید که چرا من این کار را کردم. هیچ کس نمی خواهد شخصی باشد که درست قبل از آخر هفته ساخت را بشکند.
اطمینان از یکپارچگی a خط لوله CI/CD بسیار مهم است ، به خصوص در یک Monorepo که چندین پروژه به یکدیگر بستگی دارد. یک به روزرسانی ساده برای یک بسته می تواند یک اثر موج دار داشته باشد و قبل از آنکه آن را بدانید ، نیمی از خدمات در حال شکست هستند. آیا خوب نیست که قبل از تولید آنها ، این مسائل را بدست آورید؟ این دقیقاً همان چیزی است که من برای انجام آن تصمیم گرفتم. چرا خطوط لوله آزمایش واحد؟
– خطاهای زود هنگام: قبل از رسیدن به تولید ، مسائل را تشخیص دهید.
– وابستگی ها را بررسی کنید: اطمینان حاصل کنید که تغییرات در یک پروژه دیگران را مختل نمی کند.
– بازخورد اولیه: برای کاهش استرس ، مشکلات را به سرعت شناسایی و رفع کنید.
– بهترین شیوه ها را دنبال کنید: برای حفظ کیفیت از میانبرها خودداری کنید.
– جلوگیری از خرابی های پرهزینه: حل مسائل باعث صرفه جویی در وقت و منابع می شودبشر
چگونه این کار را کردم
من استفاده کردم یدک برای تجزیه یال پرونده های خط لوله و API MSBuild برای اسکن وابستگی های پروژه. با مقایسه آنچه در خط لوله با آنچه در واقع پروژه ها به آن نیاز دارند ، اطمینان دادم که همه چیز در هم تراز شده و از شگفتی های نامطبوع جلوگیری می کند.
تجزیه yaml با yamldotnet
یدک فوق العاده است کتابخانه. نت نت برای رسیدگی یال، که عالی است زیرا بیشتر خطوط لوله CI/CD به تنظیمات YAML متکی هستند. من از آن برای خواندن و تجزیه و تحلیل تعاریف خط لوله برای استخراج مراحل ساخت و ساز مربوطه ، وابستگی ها و محرک ها استفاده کردم.
public static IEnumerable<string> GetYamlPaths(string yamlFilePath)
{
var yamlContent = File.ReadAllText(yamlFilePath);
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.IgnoreUnmatchedProperties()
.Build();
var config = deserializer.Deserialize<Yaml>(yamlContent);
return (config.Trigger.Paths.Include ?? [])
.Where(path => path.Contains("sdk", StringComparison.OrdinalIgnoreCase));
}
کلاس های لازم نشان دهنده ساختار YAML است.
public class Yaml
{
public Trigger Trigger { get; set; } = null!;
}
public class Trigger
{
public Paths Paths { get; set; } = null!;
}
public class Paths
{
public List<string>? Include { get; set; }
}
وابستگی های اسکن با API MSBuild
کد زیر اسکن نیازهای ما را نشان می دهد. این فقط با تصور شما محدود است! همچنین می توانید بسته های خارجی را نیز بررسی کنید ، یا حتی در صورت لزوم بسته های خاص را به روز کنید. امکانات بی پایان است و همه چیز به نحوه انتخاب آن بستگی دارد.
در api msbuild به من کمک کرد تا به صورت پویا وابستگی های پروژه را تجزیه و تحلیل کنم. این به ویژه در a مفید بود یکپارچه جایی که پروژه ها به یکدیگر مراجعه می کنند و تغییرات می توانند آبشار داشته باشند.
public static List<string> GetProjectDependencies(string path)
{
var solution = SolutionFile.Parse(path);
var list = new List<string>();
foreach (var projectInSolution in solution.ProjectsInOrder)
{
if (projectInSolution.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)
{
var projectPath = projectInSolution.AbsolutePath;
var project = new Project(projectPath);
var dependencies = project.Items
.Where(item => item.ItemType == "ProjectReference" &&
Path.GetFileNameWithoutExtension(item.EvaluatedInclude)
.EndsWith("_SDK", StringComparison.OrdinalIgnoreCase))
.Select(item => Path.GetFileNameWithoutExtension(item.EvaluatedInclude))
.ToList();
list.AddRange(dependencies);
ProjectCollection.GlobalProjectCollection.UnloadProject(project);
}
}
return list.Distinct().ToList();
}
آزمون زیر چه کاری انجام می دهد؟
پرونده خط لوله YAML را بارگیری کنید.
وابستگی پروژه را دریافت کنید.
هر دو لیست را با هم مقایسه کرده و تأیید کنید که آنها مطابقت دارند.
مورد آزمایش نمونه
[Fact]
public void VerifyPipelineTriggers_MatchProjectDependencies()
{
MSBuildLocator.RegisterDefaults();
var baseDirectory = AppContext.BaseDirectory;
var testsFolder = Directory.GetParent(baseDirectory)?.Parent?.Parent?.Parent?.FullName!;
var rootDirectory = Directory.GetParent(testsFolder)?.FullName!;
var yamlFilePath = Path.Combine(rootDirectory, "azure-pipelines.yml");
var sln = Path.Combine(rootDirectory, "Service.Users.sln");
var yamlPaths = PipelineTestHelper.GetYamlPaths(yamlFilePath)
.Select(c => c.Split("services")[1])
.Select(c => c.Replace("https://dev.to/", '.').TrimStart('.'))
.ToList();
var projectDependencies = PipelineTestHelper.GetProjectDependencies(sln);
Assert.True(yamlPaths.SequenceEqual(projectDependencies, StringComparer.OrdinalIgnoreCase));
}
این آزمون فقط مسیرهای موجود در پرونده YAML را بررسی می کند و آنها را با پسوند .sdk مقایسه می کند تا اطمینان حاصل شود که پروژه های SDK در خط لوله گنجانده شده است. شما می توانید آن را بر اساس نیازهای خود گسترش دهید – تخیل شما تنها حد است! به عنوان مثال ، شما می توانید آن را تقویت کنید تا از ورود برخی بسته های آسیب پذیر خاص به این پروژه جلوگیری کنید. این امر به ویژه در هنگام کار با تیم بزرگی از 40+ توسعه دهنده مفید است و اطمینان حاصل می کند که این پروژه با بهترین شیوه ها ایمن و تراز شده است.
پایان
یک خط لوله به خوبی آزمایش شده منجر به اختلال کمتری ، کاهش مداخله دستی و یک فرآیند انتشار قابل پیش بینی تر می شود. سرمایه گذاری در اعتبار سنجی خط لوله در نهایت منجر به ثبات نرم افزار بلند مدت و راندمان عملیاتی می شود.
مراحل بعدی:
برنامه ریزی تست App.Settings: بسیاری از خدمات میکروسرویس ما از همان ساختار پیروی می کنند ، و اطمینان حاصل می شود که ما از تنظیمات مشترک غافل نشویم. اجرای بررسی های اعتبار سنجی در این تنظیمات می تواند از انجام غلط و ناسازگاری در محیط ها جلوگیری کند.