<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tutorials - Software Developer's Tour</title>
	<atom:link href="https://pawelmajewski.com/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>https://pawelmajewski.com</link>
	<description>Website about programming, news in IT and more</description>
	<lastBuildDate>Wed, 11 Jun 2025 09:02:35 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>

<image>
	<url>https://pawelmajewski.com/wp-content/uploads/2024/02/logo_normal.png</url>
	<title>Tutorials - Software Developer's Tour</title>
	<link>https://pawelmajewski.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Azure DevOps Pipeline in practice</title>
		<link>https://pawelmajewski.com/azure-devops-pipeline-in-practice/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=azure-devops-pipeline-in-practice</link>
					<comments>https://pawelmajewski.com/azure-devops-pipeline-in-practice/#respond</comments>
		
		<dc:creator><![CDATA[Paweł Majewski]]></dc:creator>
		<pubDate>Sat, 15 Mar 2025 21:47:41 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Azure DevOps]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CD]]></category>
		<category><![CDATA[CI]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Pipeline]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">https://pawelmajewski.com/?p=8468</guid>

					<description><![CDATA[<p>What is Pipeline? Pipeline is a solution that automatically build, test and deploy an application. We can split Pipeline to (CI) and (CD) Pipelines. CI &#8211; Continous Integration CD &#8211; Continous Delivery/Deployment CI &#8211; helps maintain code quality by catching errors early in the development process. CD &#8211; streamlines the process of delivering code changes [&#8230;]</p>
<p>The post <a href="https://pawelmajewski.com/azure-devops-pipeline-in-practice/">Azure DevOps Pipeline in practice</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></description>
										<content:encoded><![CDATA[<div data-elementor-type="wp-post" data-elementor-id="8468" class="elementor elementor-8468">
				<div class="elementor-element elementor-element-35b07d2 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent" data-id="35b07d2" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-b625e43 elementor-widget elementor-widget-heading" data-id="b625e43" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-heading-title{padding:0;margin:0;line-height:1}.elementor-widget-heading .elementor-heading-title[class*=elementor-size-]>a{color:inherit;font-size:inherit;line-height:inherit}.elementor-widget-heading .elementor-heading-title.elementor-size-small{font-size:15px}.elementor-widget-heading .elementor-heading-title.elementor-size-medium{font-size:19px}.elementor-widget-heading .elementor-heading-title.elementor-size-large{font-size:29px}.elementor-widget-heading .elementor-heading-title.elementor-size-xl{font-size:39px}.elementor-widget-heading .elementor-heading-title.elementor-size-xxl{font-size:59px}</style><h2 class="elementor-heading-title elementor-size-default">What is Pipeline?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-bf3d0e1 elementor-widget elementor-widget-text-editor" data-id="bf3d0e1" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:#69727d;color:#fff}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap{color:#69727d;border:3px solid;background-color:transparent}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap{margin-top:8px}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap-letter{width:1em;height:1em}.elementor-widget-text-editor .elementor-drop-cap{float:left;text-align:center;line-height:1;font-size:50px}.elementor-widget-text-editor .elementor-drop-cap-letter{display:inline-block}</style>				<p>Pipeline is a solution that automatically build, test and deploy an application. We can split Pipeline to (CI) and (CD) Pipelines.</p><p><strong>CI</strong> &#8211; Continous Integration</p><p><strong>CD</strong> &#8211; Continous Delivery/Deployment</p><p><strong>CI</strong> &#8211; helps maintain code quality by catching errors early in the development process.</p><p><strong>CD</strong> &#8211; streamlines the process of delivering code changes to production environments efficiently and reliably.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-538af2b elementor-widget elementor-widget-heading" data-id="538af2b" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Use it in practice!</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-9d5c8c2 elementor-widget elementor-widget-text-editor" data-id="9d5c8c2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Today, I&#8217;ll show you how to use Azure DevOps Pipeline to deploy your application.</p><p>To follow this tutorial, go to <a title="Azure DevOps" href="https://azure.microsoft.com/en-us/products/devops" target="_blank" rel="noopener">Azure DevOps</a> and create a new project.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-195dd57 elementor-widget elementor-widget-image" data-id="195dd57" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-widget-image{text-align:center}.elementor-widget-image a{display:inline-block}.elementor-widget-image a img[src$=".svg"]{width:48px}.elementor-widget-image img{vertical-align:middle;display:inline-block}</style>										<img loading="lazy" decoding="async" loading="lazy" width="1024" height="522" src="https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline-1024x522.png" class="attachment-large size-large wp-image-8471" alt="azure_pipeline dashboard" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline-1024x522.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline-300x153.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline-768x392.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline-1536x784.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline-2048x1045.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-0886297 elementor-widget elementor-widget-text-editor" data-id="0886297" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>I created a new organization named &#8220;<strong>pawelmajewskiblog</strong>&#8221; and a project named &#8220;<strong>Pipeline example</strong>&#8220;.</p><p>Now, let&#8217;s create a sample <strong>WebAPI application</strong> that we want to deploy using <strong>Azure Pipelines</strong>.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-0d6da0e elementor-widget elementor-widget-heading" data-id="0d6da0e" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">[WebApiProject - Minimal API] Program.cs</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-a2c62e0 elementor-widget elementor-widget-code-block-for-elementor" data-id="a2c62e0" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();

var startDate = DateTime.Now;
var pipelineVariable = Environment.GetEnvironmentVariable(&quot;pipeline_variable&quot;);

app.MapGet(&quot;/&quot;, () =&gt;
{
    return new { startDate, pipelineVariable };
})
.WithName(&quot;GetVersion&quot;)
.WithOpenApi();

app.Run();
</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-b92e940 elementor-widget elementor-widget-text-editor" data-id="b92e940" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>This application contains one endpoint named <strong>GetVersion</strong>, which returns the start date of the application (<strong>startData</strong>) and the pipeline variable (<strong>pipelineVariable</strong>) that we will set in the pipeline.</p><p> </p><p>Localhost response is presented below.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-8924ea1 elementor-widget elementor-widget-image" data-id="8924ea1" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="562" src="https://pawelmajewski.com/wp-content/uploads/2024/02/localhost_response-1024x562.png" class="attachment-large size-large wp-image-8472" alt="" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/localhost_response-1024x562.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/localhost_response-300x165.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/localhost_response-768x421.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/localhost_response-1536x843.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/localhost_response-2048x1123.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-dfa3b35 elementor-widget elementor-widget-heading" data-id="dfa3b35" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Push code to the repository</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-be16993 elementor-widget elementor-widget-text-editor" data-id="be16993" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>You can add .gitignore file <a href="https://raw.githubusercontent.com/github/gitignore/main/VisualStudio.gitignore" target="_blank" rel="noopener">https://raw.githubusercontent.com/github/gitignore/main/VisualStudio.gitignore</a>.</p><p> </p>						</div>
				</div>
				<div class="elementor-element elementor-element-2e6dcd6 elementor-widget elementor-widget-image" data-id="2e6dcd6" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="418" src="https://pawelmajewski.com/wp-content/uploads/2024/02/pushed_repository-1024x418.png" class="attachment-large size-large wp-image-8483" alt="" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/pushed_repository-1024x418.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/pushed_repository-300x123.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/pushed_repository-768x314.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/pushed_repository-1536x628.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/pushed_repository-2048x837.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-baa2491 elementor-widget elementor-widget-text-editor" data-id="baa2491" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>When our repository is ready, we can go to the next step.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-714a438 elementor-widget elementor-widget-heading" data-id="714a438" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Create first pipeline</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-ecdd745 elementor-widget elementor-widget-text-editor" data-id="ecdd745" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Go to the</p>						</div>
				</div>
				<div class="elementor-element elementor-element-df75814 elementor-widget elementor-widget-image" data-id="df75814" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="560" src="https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline_create-1024x560.png" class="attachment-large size-large wp-image-8482" alt="azure_pipeline_create" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline_create-1024x560.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline_create-300x164.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline_create-768x420.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline_create-1536x840.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/azure_pipeline_create.png 1876w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-c7b20e2 elementor-widget elementor-widget-text-editor" data-id="c7b20e2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>And click &#8220;Create Pipeline&#8221;.</p><p>Select your repository, I&#8217;ll choose &#8220;Azure Repos Git&#8221;</p>						</div>
				</div>
				<div class="elementor-element elementor-element-e830ddd elementor-widget elementor-widget-text-editor" data-id="e830ddd" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Use the script for pipeline presented below</p>						</div>
				</div>
				<div class="elementor-element elementor-element-565a4ed elementor-widget elementor-widget-code-block-for-elementor" data-id="565a4ed" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-yaml'>trigger:
- master

pool:
  vmImage: &#039;ubuntu-latest&#039;

variables:
  buildConfiguration: &#039;Release&#039;

steps:
- task: UseDotNet@2
  displayName: &#039;Install .NET Core SDK&#039;
  inputs:
    version: 8.x
    
- task: DotNetCoreCLI@2
  inputs:
    command: &#039;restore&#039;
    projects: &#039;**/*.csproj&#039;
  displayName: &#039;dotnet restore $(buildConfiguration)&#039;

- task: DotNetCoreCLI@2
  inputs:
    command: &#039;build&#039;
    projects: &#039;**/*.csproj&#039;
    arguments: &#039;--configuration $(buildConfiguration)&#039;
  displayName: &#039;dotnet build $(buildConfiguration)&#039;</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-77c8f54 elementor-widget elementor-widget-text-editor" data-id="77c8f54" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>When you save this pipeline configuration file, then pipeline runs automatically for the first time.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-8ae5638 elementor-widget elementor-widget-image" data-id="8ae5638" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_00-1024x525.png" class="attachment-large size-large wp-image-8505" alt="pipeline queued" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_00-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_00-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_00-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_00-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_00-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_00-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-f7900c3 elementor-widget elementor-widget-image" data-id="f7900c3" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_28-1024x525.png" class="attachment-large size-large wp-image-8506" alt="pipeline in progress" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_28-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_28-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_28-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_28-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_28-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_28-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-9c253ab elementor-widget elementor-widget-image" data-id="9c253ab" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_37-1024x525.png" class="attachment-large size-large wp-image-8507" alt="pipeline success last step" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_37-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_37-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_37-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_37-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_37-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_37-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-3b6ff5b elementor-widget elementor-widget-image" data-id="3b6ff5b" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_49-1024x525.png" class="attachment-large size-large wp-image-8508" alt="pipeline branch success" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_49-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_49-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_49-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_49-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_49-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h22_49-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-bc97113 elementor-widget elementor-widget-image" data-id="bc97113" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="525" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h26_37-1024x525.png" class="attachment-large size-large wp-image-8509" alt="pipeline list success" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h26_37-1024x525.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h26_37-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h26_37-768x394.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h26_37-1536x788.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h26_37-2048x1050.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h26_37-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-47d106a elementor-widget elementor-widget-text-editor" data-id="47d106a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>When the pipeline finishes its work, you will be notified by email.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-abf1119 elementor-widget elementor-widget-image" data-id="abf1119" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="501" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h27_52-1024x501.png" class="attachment-large size-large wp-image-8510" alt="build success" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h27_52-1024x501.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h27_52-300x147.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h27_52-768x376.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h27_52-1536x752.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h27_52-2048x1002.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-5a560e2 elementor-widget elementor-widget-text-editor" data-id="5a560e2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>We&#8217;ll also receive an email when the build fails.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-e064117 elementor-widget elementor-widget-image" data-id="e064117" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="528" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h28_59-1024x528.png" class="attachment-large size-large wp-image-8511" alt="build failed" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h28_59-1024x528.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h28_59-300x155.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h28_59-768x396.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h28_59-1536x791.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h28_59-2048x1055.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-c10c057 elementor-widget elementor-widget-image" data-id="c10c057" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="548" src="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h29_11-1-1024x548.png" class="attachment-large size-large wp-image-8519" alt="build canceled" srcset="https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h29_11-1-1024x548.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h29_11-1-300x160.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h29_11-1-768x411.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h29_11-1-1536x822.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/04/2024-04-04_22h29_11-1-2048x1095.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
					</div>
				</div>
				</div><p>The post <a href="https://pawelmajewski.com/azure-devops-pipeline-in-practice/">Azure DevOps Pipeline in practice</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://pawelmajewski.com/azure-devops-pipeline-in-practice/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to create simple healthcheck in 5 minutes</title>
		<link>https://pawelmajewski.com/how-to-create-simple-healthcheck-in-5-minutes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-create-simple-healthcheck-in-5-minutes</link>
					<comments>https://pawelmajewski.com/how-to-create-simple-healthcheck-in-5-minutes/#respond</comments>
		
		<dc:creator><![CDATA[Paweł Majewski]]></dc:creator>
		<pubDate>Tue, 04 Mar 2025 17:07:00 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[downtime]]></category>
		<category><![CDATA[Healthcheck]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[Website]]></category>
		<guid isPermaLink="false">https://pawelmajewski.com/?p=8648</guid>

					<description><![CDATA[<p>In the past, when I used a different hosting provider than I do now, I often encountered situations where the website was unavailable. How can we check if a website is accessible without constantly refreshing it in the browser? Just write your own app! First, let&#8217;s think about what we want to do. Application requirements [&#8230;]</p>
<p>The post <a href="https://pawelmajewski.com/how-to-create-simple-healthcheck-in-5-minutes/">How to create simple healthcheck in 5 minutes</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></description>
										<content:encoded><![CDATA[<div data-elementor-type="wp-post" data-elementor-id="8648" class="elementor elementor-8648">
				<div class="elementor-element elementor-element-0171db9 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent" data-id="0171db9" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-fa1f027 elementor-widget elementor-widget-text-editor" data-id="fa1f027" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>In the past, when I used a different hosting provider than I do now, I often encountered situations where the website was unavailable.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-8bfb469 elementor-widget elementor-widget-heading" data-id="8bfb469" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">How can we check if a website is accessible without constantly refreshing it in the browser?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-b857a05 elementor-widget elementor-widget-heading" data-id="b857a05" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Just write your own app!</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-cf7f752 elementor-widget elementor-widget-text-editor" data-id="cf7f752" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>First, let&#8217;s think about what we want to do.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-89581b2 poket-star-rating--align-center elementor-widget elementor-widget-witr_section_list" data-id="89581b2" data-element_type="widget" data-widget_type="witr_section_list.default">
				<div class="elementor-widget-container">
					
			<div class="departmentList all_list_color">
				<!-- title -->
								<h3>Application requirements </h3>
				
					<ul>
																		<li>
																<span>
																			<i class="fas fa-angle-double-right"></i>
									We want the ability to pass multiple URLs to the application								</span>
							</li>
													<li>
																<span>
																			<i class="fas fa-angle-double-right"></i>
									We haven't time, so our choice will be Console application😊								</span>
							</li>
													<li>
																<span>
																			<i class="fas fa-angle-double-right"></i>
									The application should inform us whether the request has returned a success status code or has failed.								</span>
							</li>
													<li>
																<span>
																			<i class="fas fa-angle-double-right"></i>
									To avoid being banned for DDoS, the application should incorporate a delay.between requests								</span>
							</li>
											
					</ul>					
				<!-- button -->
								
			</div>		

				</div>
				</div>
				<div class="elementor-element elementor-element-0c58aaf elementor-widget elementor-widget-text-editor" data-id="0c58aaf" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>You can read more about <a href="https://en.wikipedia.org/wiki/Denial-of-service_attack" target="_blank" rel="noopener">DDoS attack here</a>.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-0ea7e6c elementor-alert-danger elementor-widget elementor-widget-alert" data-id="0ea7e6c" data-element_type="widget" data-widget_type="alert.default">
				<div class="elementor-widget-container">
			<style>/*! elementor - v3.21.0 - 08-05-2024 */
.elementor-alert{padding:15px;border-left:5px solid transparent;position:relative;text-align:start}.elementor-alert .elementor-alert-title{display:block;font-weight:700}.elementor-alert .elementor-alert-description{font-size:13px}.elementor-alert button.elementor-alert-dismiss{position:absolute;right:var(--dismiss-icon-horizontal-position,10px);top:var(--dismiss-icon-vertical-position,10px);padding:3px;font-size:var(--dismiss-icon-size,20px);line-height:1;background:transparent;color:var(--dismiss-icon-normal-color,inherit);border:none;cursor:pointer;transition-duration:var(--dismiss-icon-hover-transition-duration,.3s)}.elementor-alert button.elementor-alert-dismiss:hover{color:var(--dismiss-icon-hover-color,inherit)}.elementor-alert button.elementor-alert-dismiss svg{width:var(--dismiss-icon-size,20px);height:var(--dismiss-icon-size,20px);fill:var(--dismiss-icon-normal-color,currentColor);transition-duration:var(--dismiss-icon-hover-transition-duration,.3s)}.elementor-alert button.elementor-alert-dismiss svg:hover{fill:var(--dismiss-icon-hover-color,currentColor)}.elementor-alert-info .elementor-alert{color:#31708f;background-color:#d9edf7;border-color:#bcdff1}.elementor-alert-success .elementor-alert{color:#3c763d;background-color:#dff0d8;border-color:#cae6be}.elementor-alert-warning .elementor-alert{color:#8a6d3b;background-color:#fcf8e3;border-color:#f9f0c3}.elementor-alert-danger .elementor-alert{color:#a94442;background-color:#f2dede;border-color:#e8c4c4}@media (max-width:767px){.elementor-alert{padding:10px}.elementor-alert button.elementor-alert-dismiss{right:7px;top:7px}}</style>		<div class="elementor-alert" role="alert">

						<span class="elementor-alert-title">Possibility of being banned</span>
			
						<span class="elementor-alert-description">You have to handle the given code very carefully, as placing the delay incorrectly could result in your application unintentionally launching DDoS attacks on the provided websites.</span>
			
						<button type="button" class="elementor-alert-dismiss">
									<span aria-hidden="true">&times;</span>
								<span class="elementor-screen-only">Dismiss this alert.</span>
			</button>
			
		</div>
				</div>
				</div>
				<div class="elementor-element elementor-element-a2b9181 elementor-widget elementor-widget-text-editor" data-id="a2b9181" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>I will paste here entire code and then we&#8217;ll talk about it closer.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-f061941 elementor-widget elementor-widget-code-block-for-elementor" data-id="f061941" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>class Program
{
    static async Task Main(string[] args)
    {
        const string fileName = &quot;sites.txt&quot;;
        TimeSpan delay = TimeSpan.FromSeconds(10);
        var fileContent = await ValidateFileAsync(fileName);
        var urlsWithClients = PrepareUrls(fileContent);

        await RunInfinity(urlsWithClients, delay);
    }

    static async Task&lt;bool&gt; IsAliveAsync(HttpClient httpClient)
    {
        try
        {
            var result = await httpClient.GetAsync(string.Empty);

            return result.IsSuccessStatusCode;
        } catch
        {

        }

        return false;
    }

    static async Task&lt;string[]&gt; ValidateFileAsync(string filePath)
    {
        var doesFileExist = File.Exists(filePath);

        if (!doesFileExist)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(&quot;Couldn&#039;t find file&quot;);
            Console.ResetColor();

            return [];
        }

        var fileContent = await File.ReadAllLinesAsync(filePath);

        if(!fileContent.Any())
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(&quot;There is no url in file&quot;);
            Console.ResetColor();
        }

        return fileContent;
    }

    static (string Url, HttpClient httpClient)[] PrepareUrls(IEnumerable&lt;string&gt; urls)
    {
        return urls.Select(x =&gt; {
            var httpClient = new HttpClient
            {
                BaseAddress = new Uri(x)
            };

            return (x, httpClient);
        }).ToArray();
    }

    static Task RunInfinity(IEnumerable&lt;(string Url, HttpClient httpClient)&gt; urls, TimeSpan delay)
    {
        return Task.Run(async () =&gt;
        {
            while (true)
            {
                foreach (var (x, httpClient) in urls)
                {
                    var isAlive = await IsAliveAsync(httpClient);

                    Console.Write($&quot;{DateTime.Now:dd-MM HH:mm:ss}\tUrl: {x}\t&quot;);
                    if (isAlive)
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine(&quot;OK&quot;);
                    }
                    else
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine(&quot;FAILED&quot;);
                    }
                    Console.ResetColor();

                }

                await Task.Delay(delay);
            }
        });
    }
}</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-5ab100c elementor-widget elementor-widget-text-editor" data-id="5ab100c" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Let&#8217;s start analyzing 🙂</p>						</div>
				</div>
				<div class="elementor-element elementor-element-f9b869a elementor-widget elementor-widget-text-editor" data-id="f9b869a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>The main function</p>						</div>
				</div>
				<div class="elementor-element elementor-element-4d8737c elementor-widget elementor-widget-code-block-for-elementor" data-id="4d8737c" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>        const string fileName = &quot;sites.txt&quot;;
        TimeSpan delay = TimeSpan.FromSeconds(10);
        var fileContent = await ValidateFileAsync(fileName);
        var urlsWithClients = PrepareUrls(fileContent);

        await RunInfinity(urlsWithClients, delay);</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-0bb7bdf elementor-widget elementor-widget-text-editor" data-id="0bb7bdf" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>First two lines are our configuration. When creating this application, I assumed that the user will provide urls to check in file named sites.txt and this file will be next to .exe file. I aimed to keep it as straightforward as I could.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-dbfc2ae elementor-widget elementor-widget-text-editor" data-id="dbfc2ae" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Then we have simple validation, I think we can just skip it. I added it only because I got an exception during development 😁</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d1f437c elementor-widget elementor-widget-text-editor" data-id="d1f437c" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>I didn&#8217;t want to read the file twice, so the validation function immediately passes on the read data.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d876165 elementor-widget elementor-widget-code-block-for-elementor" data-id="d876165" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>    static (string Url, HttpClient httpClient)[] PrepareUrls(IEnumerable&lt;string&gt; urls)
    {
        return urls.Select(x =&gt; {
            var httpClient = new HttpClient
            {
                BaseAddress = new Uri(x)
            };

            return (x, httpClient);
        }).ToArray();
    }</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-73aecbe elementor-widget elementor-widget-text-editor" data-id="73aecbe" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>I think this is a good place to refactor. We don&#8217;t need a <strong>tuple</strong> with a <strong>string</strong> and <strong>HttpClient</strong> here. Since <strong>HttpClient</strong> already contains <strong>BaseAddress</strong> itself, we could retrieve this information directly from it.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-5562e61 elementor-widget elementor-widget-text-editor" data-id="5562e61" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Function <strong>IsAliveAsync</strong> is only wrapper for <strong>GetAsync</strong> method.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-48ea889 elementor-widget elementor-widget-text-editor" data-id="48ea889" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>And last our system&#8217;s core, our heart beating method</p>						</div>
				</div>
				<div class="elementor-element elementor-element-9fc7dee elementor-widget elementor-widget-code-block-for-elementor" data-id="9fc7dee" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>        return Task.Run(async () =&gt;
        {
            while (true)
            {
                foreach (var (x, httpClient) in urls)
                {
                    var isAlive = await IsAliveAsync(httpClient);

                    Console.Write($&quot;{DateTime.Now:dd-MM HH:mm:ss}\tUrl: {x}\t&quot;);
                    if (isAlive)
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine(&quot;OK&quot;);
                    }
                    else
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine(&quot;FAILED&quot;);
                    }
                    Console.ResetColor();

                }

                await Task.Delay(delay);
            }
        });</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-7c7c972 elementor-widget elementor-widget-text-editor" data-id="7c7c972" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>What are we doing here? There are just two loops, one while loop, which with Task.Delay (line 24) will be our beating heart.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-ab65c67 elementor-widget elementor-widget-text-editor" data-id="ab65c67" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Inside while loop is loop over our urls and and that&#8217;s it, no philosophy involved.</p><p>Additionally, one &#8220;if&#8221; statement to check whether the request was successful or not.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-259e9a5 elementor-widget elementor-widget-heading" data-id="259e9a5" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">How it works?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-26480f9 elementor-widget elementor-widget-text-editor" data-id="26480f9" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Create file with urls</p>						</div>
				</div>
				<div class="elementor-element elementor-element-34c115c elementor-widget elementor-widget-image" data-id="34c115c" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="288" height="150" src="https://pawelmajewski.com/wp-content/uploads/2024/03/2024-05-06_19h54_07.png" class="attachment-large size-large wp-image-8663" alt="file with urls" />													</div>
				</div>
				<div class="elementor-element elementor-element-7e2a670 elementor-widget elementor-widget-text-editor" data-id="7e2a670" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Start application</p>						</div>
				</div>
				<div class="elementor-element elementor-element-36b6193 elementor-widget elementor-widget-image" data-id="36b6193" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="979" height="512" src="https://pawelmajewski.com/wp-content/uploads/2024/03/2024-05-06_18h56_02.png" class="attachment-large size-large wp-image-8662" alt="application result" srcset="https://pawelmajewski.com/wp-content/uploads/2024/03/2024-05-06_18h56_02.png 979w, https://pawelmajewski.com/wp-content/uploads/2024/03/2024-05-06_18h56_02-300x157.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/03/2024-05-06_18h56_02-768x402.png 768w" sizes="auto, (max-width: 979px) 100vw, 979px" />													</div>
				</div>
				<div class="elementor-element elementor-element-7073ea9 elementor-widget elementor-widget-heading" data-id="7073ea9" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">At the end</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-2e5198f elementor-widget elementor-widget-text-editor" data-id="2e5198f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>I strongly encourage you to write simple applications. Writing one can take as much time as finding the right one online.</p>						</div>
				</div>
					</div>
				</div>
				</div><p>The post <a href="https://pawelmajewski.com/how-to-create-simple-healthcheck-in-5-minutes/">How to create simple healthcheck in 5 minutes</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://pawelmajewski.com/how-to-create-simple-healthcheck-in-5-minutes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Introduction to Jenkins and Pipelines</title>
		<link>https://pawelmajewski.com/introduction-to-jenkins-and-pipelines/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introduction-to-jenkins-and-pipelines</link>
					<comments>https://pawelmajewski.com/introduction-to-jenkins-and-pipelines/#respond</comments>
		
		<dc:creator><![CDATA[Paweł Majewski]]></dc:creator>
		<pubDate>Wed, 05 Feb 2025 16:40:30 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CD]]></category>
		<category><![CDATA[CI]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Pipeline]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">https://pawelmajewski.com/?p=8490</guid>

					<description><![CDATA[<p>What is Pipeline? Pipeline is a solution that automatically build, test and deploy an application. We can split Pipeline to (CI) and (CD) Pipelines. CI &#8211; Continous Integration CD &#8211; Continous Delivery/Deployment CI &#8211; helps maintain code quality by catching errors early in the development process. CD &#8211; streamlines the process of delivering code changes [&#8230;]</p>
<p>The post <a href="https://pawelmajewski.com/introduction-to-jenkins-and-pipelines/">Introduction to Jenkins and Pipelines</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></description>
										<content:encoded><![CDATA[<div data-elementor-type="wp-post" data-elementor-id="8490" class="elementor elementor-8490">
				<div class="elementor-element elementor-element-8cdd5fe e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent" data-id="8cdd5fe" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-9abd84a elementor-widget elementor-widget-heading" data-id="9abd84a" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">What is Pipeline?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-2463429 elementor-widget elementor-widget-text-editor" data-id="2463429" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Pipeline is a solution that automatically build, test and deploy an application. We can split Pipeline to (CI) and (CD) Pipelines.</p><p><strong>CI</strong> &#8211; Continous Integration</p><p><strong>CD</strong> &#8211; Continous Delivery/Deployment</p><p><strong>CI</strong> &#8211; helps maintain code quality by catching errors early in the development process.</p><p><strong>CD</strong> &#8211; streamlines the process of delivering code changes to production environments efficiently and reliably.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-c1cf971 elementor-widget elementor-widget-heading" data-id="c1cf971" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Use it in practice!</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-f2f182c elementor-widget elementor-widget-text-editor" data-id="f2f182c" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Today, I&#8217;ll show you how to use Jenkins to create CI for your application.</p><p>To follow this tutorial, go to https://www.jenkins.io/doc/book/installing/ and install Jenkins.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-2e2e88a elementor-widget elementor-widget-heading" data-id="2e2e88a" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Create console application in Visual Studio</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-58db5f9 elementor-widget elementor-widget-code-block-for-elementor" data-id="58db5f9" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>﻿Console.WriteLine($&quot;It works&quot;);</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-8c62396 elementor-widget elementor-widget-text-editor" data-id="8c62396" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Push it to your remote repository. You can see an example  on <a title="https://github.com/MajewskiPawel/app-ci-cd" href="https://github.com/MajewskiPawel/app-ci-cd" target="_blank" rel="noopener">https://github.com/MajewskiPawel/app-ci-cd</a></p>						</div>
				</div>
				<div class="elementor-element elementor-element-719b744 elementor-widget elementor-widget-heading" data-id="719b744" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Use Jenkins!</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-61705f8 elementor-widget elementor-widget-text-editor" data-id="61705f8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>If your repository is private, you&#8217;ll need to add credentials to authorize Jenkins with your Git provider. Navigate to Dashboard -&gt; Manage Jenkins -&gt; Credentials -&gt; System -&gt; Global credentials (unrestricted).</p>						</div>
				</div>
				<div class="elementor-element elementor-element-a820de8 elementor-widget elementor-widget-text-editor" data-id="a820de8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>When you click &#8220;Add credentials&#8221; button choose &#8220;<strong>SSH Username with private key</strong>&#8221; in &#8220;Kind&#8221; field.</p><p>&#8220;<strong>Username</strong>&#8221; &#8211; username or email</p><p>&#8220;<strong>Private Key</strong>&#8221; -&gt; click &#8220;<strong>Enter directly</strong>&#8220;</p><p>To add Private Key you need public and private key. </p>						</div>
				</div>
				<div class="elementor-element elementor-element-f9c087f elementor-widget elementor-widget-image" data-id="f9c087f" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="979" height="512" src="https://pawelmajewski.com/wp-content/uploads/2024/02/Generate-SSH.png" class="attachment-large size-large wp-image-8492" alt="Generate SSH" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/Generate-SSH.png 979w, https://pawelmajewski.com/wp-content/uploads/2024/02/Generate-SSH-300x157.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/Generate-SSH-768x402.png 768w" sizes="auto, (max-width: 979px) 100vw, 979px" />													</div>
				</div>
				<div class="elementor-element elementor-element-f391db9 elementor-widget elementor-widget-text-editor" data-id="f391db9" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>After this, you will find both <strong>jenkins</strong> and <strong>jenkins.pub</strong> files in your user directory.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-298aa47 elementor-widget elementor-widget-text-editor" data-id="298aa47" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Open <b>jenkins.pub</b> file, copy entire value and paste it in your profile configuration on your git provider (example for GitHub is presented below).</p>						</div>
				</div>
				<div class="elementor-element elementor-element-71cca03 elementor-widget elementor-widget-image" data-id="71cca03" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="521" src="https://pawelmajewski.com/wp-content/uploads/2024/02/Add-ssh-github-1024x521.png" class="attachment-large size-large wp-image-8494" alt="" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/Add-ssh-github-1024x521.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/Add-ssh-github-300x153.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/Add-ssh-github-768x391.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/Add-ssh-github-1536x781.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/Add-ssh-github-2048x1042.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-4a5824e elementor-widget elementor-widget-text-editor" data-id="4a5824e" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Open <b>jenkins </b>file (without pub extension), copy entire value and paste it in <strong>Private Key</strong> field in Jenkins credentials configurator.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-f012bac elementor-widget elementor-widget-image" data-id="f012bac" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="254" src="https://pawelmajewski.com/wp-content/uploads/2024/02/Jenkins-credentials-added-1024x254.png" class="attachment-large size-large wp-image-8493" alt="Jenkins credentials added" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/Jenkins-credentials-added-1024x254.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/Jenkins-credentials-added-300x74.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/Jenkins-credentials-added-768x191.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/Jenkins-credentials-added-1536x381.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/Jenkins-credentials-added-2048x508.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-74d677d elementor-widget elementor-widget-text-editor" data-id="74d677d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>After saving the form, you should see a list of credentials. Save the ID of the created element because we will need it later.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-b0cd23a elementor-widget elementor-widget-heading" data-id="b0cd23a" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Create new pipeline</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-d594b5f elementor-widget elementor-widget-text-editor" data-id="d594b5f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>On the main dashboard click &#8220;<strong>New Item</strong>&#8221; and add new Pipeline</p>						</div>
				</div>
				<div class="elementor-element elementor-element-7ba7c7e elementor-widget elementor-widget-image" data-id="7ba7c7e" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="519" src="https://pawelmajewski.com/wp-content/uploads/2024/02/Create-new-pipeline-1024x519.png" class="attachment-large size-large wp-image-8495" alt="Create new pipeline" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/Create-new-pipeline-1024x519.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/Create-new-pipeline-300x152.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/Create-new-pipeline-768x389.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/Create-new-pipeline-1536x778.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/Create-new-pipeline-2048x1038.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-8c8e54f elementor-widget elementor-widget-text-editor" data-id="8c8e54f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Below is the script I have created to build previously created application.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-6210f80 elementor-widget elementor-widget-code-block-for-elementor" data-id="6210f80" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-javascript'>pipeline {
    agent any
    
    stages {
        stage (&#039;Git&#039;) {
            steps {
                git branch: &#039;main&#039;, credentialsId: &#039;test-application&#039;, url: &#039;https://github.com/MajewskiPawel/app-ci-cd&#039;
            }
        }
        stage(&#039;Restore packages&#039;) {
            steps {
                powershell &quot;dotnet restore &#039;${workspace}\\App\\App.sln&#039;&quot;
            }
        }
        stage(&#039;Build project&#039;) {
            steps {
                powershell &quot;dotnet build --configuration Release &#039;${workspace}\\App\\App.csproj&#039;&quot;
            }
        }
    }
}</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-056097b elementor-widget elementor-widget-heading" data-id="056097b" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Run it!</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-c068bf6 elementor-widget elementor-widget-text-editor" data-id="c068bf6" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Click &#8220;<strong>Build Now</strong>&#8221; button on the left navigation bar and see the magic.</p><p>We can configure Jenkins to synchronize with Git events and our builds can be executed when pull request have been created or when we push something to master branch.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-05d3a7d elementor-widget elementor-widget-image" data-id="05d3a7d" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="482" src="https://pawelmajewski.com/wp-content/uploads/2024/02/Build-success-1024x482.png" class="attachment-large size-large wp-image-8496" alt="Build success" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/Build-success-1024x482.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-success-300x141.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-success-768x362.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-success-1536x723.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-success-2048x964.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-2dceb00 elementor-widget elementor-widget-heading" data-id="2dceb00" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Why are we doing this?</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-2c98b64 elementor-widget elementor-widget-text-editor" data-id="2c98b64" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Before I explain, please modify your application code to the presented below.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-2adb18b elementor-widget elementor-widget-code-block-for-elementor" data-id="2adb18b" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>var z = 
Console.WriteLine($&quot;It works&quot;);</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-dcb6bac elementor-widget elementor-widget-text-editor" data-id="dcb6bac" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>and push it to your repository.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-99624b9 elementor-widget elementor-widget-text-editor" data-id="99624b9" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Click &#8220;<strong>Build Now</strong>&#8221; button again.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-4a47bd1 elementor-widget elementor-widget-image" data-id="4a47bd1" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="1024" height="524" src="https://pawelmajewski.com/wp-content/uploads/2024/02/Build-failed-1024x524.png" class="attachment-large size-large wp-image-8497" alt="Build failed" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/Build-failed-1024x524.png 1024w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-failed-300x154.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-failed-768x393.png 768w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-failed-1536x786.png 1536w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-failed-2048x1048.png 2048w, https://pawelmajewski.com/wp-content/uploads/2024/02/Build-failed-1170x600.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" />													</div>
				</div>
				<div class="elementor-element elementor-element-c811211 elementor-widget elementor-widget-text-editor" data-id="c811211" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>If we had it connected to Git events, we would know immediately when our code has failed, right after someone pushed it to the main branch.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-58d9337 elementor-widget elementor-widget-text-editor" data-id="58d9337" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Everything we just did is called CI. Not so scary, right :)?</p>						</div>
				</div>
					</div>
				</div>
				</div><p>The post <a href="https://pawelmajewski.com/introduction-to-jenkins-and-pipelines/">Introduction to Jenkins and Pipelines</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://pawelmajewski.com/introduction-to-jenkins-and-pipelines/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Why is testing our apps so important?</title>
		<link>https://pawelmajewski.com/why-is-testing-our-apps-so-important/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-is-testing-our-apps-so-important</link>
					<comments>https://pawelmajewski.com/why-is-testing-our-apps-so-important/#respond</comments>
		
		<dc:creator><![CDATA[Paweł Majewski]]></dc:creator>
		<pubDate>Sat, 25 Jan 2025 19:10:04 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Unit Tests]]></category>
		<guid isPermaLink="false">https://pawelmajewski.com/?p=8452</guid>

					<description><![CDATA[<p>Hi, today I would like to address the next topic &#8211; testing.  The example that will be shown today is trivial, but it will effectively illustrate what can go wrong due to writing target code too quickly without testing. There are many types of tests but today, I&#8217;ll focus on unit tests. Firstly, let&#8217;s take [&#8230;]</p>
<p>The post <a href="https://pawelmajewski.com/why-is-testing-our-apps-so-important/">Why is testing our apps so important?</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></description>
										<content:encoded><![CDATA[<div data-elementor-type="wp-post" data-elementor-id="8452" class="elementor elementor-8452">
				<div class="elementor-element elementor-element-555d9b0 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent" data-id="555d9b0" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-fc05ec3 elementor-widget elementor-widget-text-editor" data-id="fc05ec3" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Hi, today I would like to address the next topic &#8211; testing. </p><p>The example that will be shown today is trivial, but it will effectively illustrate what can go wrong due to writing target code too quickly without testing.</p><p>There are many types of tests but today, I&#8217;ll focus on unit tests.</p><p>Firstly, let&#8217;s take a look at the simple project structure presented below.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-3f99ea6 elementor-widget elementor-widget-image" data-id="3f99ea6" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="278" height="299" src="https://pawelmajewski.com/wp-content/uploads/2024/02/project_structure.png" class="attachment-large size-large wp-image-8455" alt="project_structure" />													</div>
				</div>
				<div class="elementor-element elementor-element-b31dde2 elementor-widget elementor-widget-text-editor" data-id="b31dde2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>We have 3 projects.</p><ol><li>Calculator.Console &#8211; it&#8217;s console project application.</li><li>Calculator.Engine &#8211; it&#8217;s a library application; this is where all of our application logic will reside.<ol><li>Calculator.Engine.Tests &#8211; the final project is where we will consolidate all our tests related to the Calculator.Engine project.</li></ol></li></ol>						</div>
				</div>
				<div class="elementor-element elementor-element-d643068 elementor-widget elementor-widget-heading" data-id="d643068" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">[Calculator.Console] Program.cs</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-c5ea18d elementor-widget elementor-widget-code-block-for-elementor" data-id="c5ea18d" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>using Calculator.Engine;

Console.WriteLine(&quot;Function -&gt; Add&quot;);
Console.Write(&quot;X = &quot;);
var x = double.Parse(Console.ReadLine());
Console.Write(&quot;Y = &quot;);
var y = double.Parse(Console.ReadLine());
var z = MathEngine.Add(x, y);

Console.WriteLine($&quot;Output = {z}&quot;);
</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-d3bff33 elementor-widget elementor-widget-text-editor" data-id="d3bff33" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>The application is quite basic, lacking any form of validation etc.</p><p>It prompts the user for two numbers and returns the sum of these elements as the result.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-305593e elementor-widget elementor-widget-heading" data-id="305593e" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">[Calculator.Engine] MathEngine.cs</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-72119a8 elementor-widget elementor-widget-code-block-for-elementor" data-id="72119a8" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>namespace Calculator.Engine;

public class MathEngine
{
    public static double Add(double x, double y)
    {
        return x - y;
    } 
}
</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-146558a elementor-widget elementor-widget-text-editor" data-id="146558a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>This project is a brain of our application. As you can see the result of <b>Add</b> operation is wrong (x &#8211; y instead of x + y) but developer doesn&#8217;t know that.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-b5801fb elementor-widget elementor-widget-heading" data-id="b5801fb" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">[Calculator.Engine.Tests] AddTests</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-5c9884f elementor-widget elementor-widget-code-block-for-elementor" data-id="5c9884f" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-csharp'>using Calculator.Engine;
using FluentAssertions;

namespace Calculator.Tests
{
    public class Tests
    {
        [Test]
        public void Returns_Valid()
        {
            // Arrange
            var x = 2;
            var y = 3;

            // Act
            var z = MathEngine.Add(x, y);

            // Assert
            z.Should().Be(5, because: &quot;2 + 3 = 5&quot;);
        }

        [Test]
        public void Returns_Valid_X_Negative_Y_Positive()
        {
            // Arrange
            var x = -2;
            var y = 3;

            // Act
            var z = MathEngine.Add(x, y);

            // Assert
            z.Should().Be(1, because: &quot;-2 + 3 = 1&quot;);
        }
    }
}</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-0171fe2 elementor-widget elementor-widget-text-editor" data-id="0171fe2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>This project uses FluentAssertion overriding base assertions that comes with NUnit.</p><p>The first method, Returns_Valid, initializes the components required for addition. The result of Add operation should be 5 but, in MathEngine is &#8211; instead of +. Second method does the same but first component is negative.</p><p>Let&#8217;s then look at the test results in this form.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-07fff77 elementor-widget elementor-widget-image" data-id="07fff77" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="862" height="227" src="https://pawelmajewski.com/wp-content/uploads/2024/02/tests_result-1.png" class="attachment-large size-large wp-image-8462" alt="tests_result" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/tests_result-1.png 862w, https://pawelmajewski.com/wp-content/uploads/2024/02/tests_result-1-300x79.png 300w, https://pawelmajewski.com/wp-content/uploads/2024/02/tests_result-1-768x202.png 768w" sizes="auto, (max-width: 862px) 100vw, 862px" />													</div>
				</div>
				<div class="elementor-element elementor-element-dd3af04 elementor-widget elementor-widget-text-editor" data-id="dd3af04" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>FluentAssertions is named &#8220;Fluent&#8221;, because you can read the code like speech in real language.</p><p>We can see that both tests have failed. it is now possible to investigate to find the error.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-828bff2 elementor-widget elementor-widget-heading" data-id="828bff2" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">[Calculator.Engine] MathEngine.cs</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-a291236 elementor-widget elementor-widget-code-block-for-elementor" data-id="a291236" data-element_type="widget" data-widget_type="code-block-for-elementor.default">
				<div class="elementor-widget-container">
			<pre class='line-numbers theme-okaidia' data-show-toolbar='yes'><code class='language-javascript'>namespace Calculator.Engine;

public class MathEngine
{
    public static double Add(double x, double y)
    {
        return x + y;
    } 
}
</code></pre>		</div>
				</div>
				<div class="elementor-element elementor-element-3110982 elementor-widget elementor-widget-text-editor" data-id="3110982" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>When I fix the bug with replacing &#8211; with +, I&#8217;ll start the tests again and see what happens.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-ab7a842 elementor-widget elementor-widget-image" data-id="ab7a842" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" loading="lazy" width="547" height="236" src="https://pawelmajewski.com/wp-content/uploads/2024/02/test_success.png" class="attachment-large size-large wp-image-8463" alt="test_success" srcset="https://pawelmajewski.com/wp-content/uploads/2024/02/test_success.png 547w, https://pawelmajewski.com/wp-content/uploads/2024/02/test_success-300x129.png 300w" sizes="auto, (max-width: 547px) 100vw, 547px" />													</div>
				</div>
				<div class="elementor-element elementor-element-a1e341c elementor-widget elementor-widget-text-editor" data-id="a1e341c" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Everything works fine. The tests have passed, and the code is correct now.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-0a5dbf2 elementor-widget elementor-widget-heading" data-id="0a5dbf2" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Summary</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-d579a9a elementor-widget elementor-widget-text-editor" data-id="d579a9a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>This trivial example of a unit test can show us how important testing our applications is. Without tests, this code would likely be returned to development as a failed task or bug.</p>						</div>
				</div>
					</div>
				</div>
				</div><p>The post <a href="https://pawelmajewski.com/why-is-testing-our-apps-so-important/">Why is testing our apps so important?</a> first appeared on <a href="https://pawelmajewski.com">Software Developer's Tour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://pawelmajewski.com/why-is-testing-our-apps-so-important/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
