<?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>Testing Tools &#8211; Few Steps &#8211; ก้าวสั้นๆ แต่ไปเรื่อยๆ</title>
	<atom:link href="https://myifew.com/tag/testing-tools/feed/" rel="self" type="application/rss+xml" />
	<link>https://myifew.com</link>
	<description></description>
	<lastBuildDate>Mon, 11 May 2020 03:54:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://myifew.com/wp-content/uploads/2018/07/cropped-logo6-ts-32x32.png</url>
	<title>Testing Tools &#8211; Few Steps &#8211; ก้าวสั้นๆ แต่ไปเรื่อยๆ</title>
	<link>https://myifew.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>แนะนำ k6 สำหรับทำ Load  Testing และ Automation Testing</title>
		<link>https://myifew.com/5669/k6-load-testing-tool/</link>
					<comments>https://myifew.com/5669/k6-load-testing-tool/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Thu, 02 Apr 2020 17:41:51 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Performance Test]]></category>
		<category><![CDATA[Testing Tools]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=5669</guid>

					<description><![CDATA[ในบรรดาเครื่องมือ Load Test ที่เรารู้จักกันคงหนีไม่พ้น ab (ApacheBench) และ Apache jMeter โพสต์นี้จะมาแนะนำอีกตัวหนึ่ง ที่ Developer น่าจะชอบเลย ชื่อว่า k6 ครับ Performance Testing,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>ในบรรดาเครื่องมือ Load Test ที่เรารู้จักกันคงหนีไม่พ้น <a href="http://httpd.apache.org/docs/2.4/programs/ab.html">ab (ApacheBench)</a> และ <a href="https://jmeter.apache.org/">Apache jMeter</a> โพสต์นี้จะมาแนะนำอีกตัวหนึ่ง ที่ Developer น่าจะชอบเลย ชื่อว่า <a href="https://k6.io/">k6</a> ครับ</p>



<span id="more-5669"></span>



<h2 class="wp-block-heading">Performance Testing, Load Testing กับ Stress Testing ต่างกันอย่างไร</h2>



<p>ก่อนจะไปถึงเครื่องมือ มาทำความเข้าใจกันก่อนว่า Test ทั้ง 3 ตัวนี้ ต่างกันอย่างไร </p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="774" height="467" src="https://myifew.com/wp-content/uploads/2020/04/performance-test-type.png" alt="" class="wp-image-5681"/></figure>



<p>ต้องบอกว่า Load Testing และ Stress Testing เป็นส่วนหนึ่งใน Performance Testing ซึ่งคือ การที่เราทดสอบในแง่มุมต่างๆ เพื่อบ่งบอกประสิทธิภาพของระบบ เช่น</p>



<ul class="wp-block-list"><li>ระบบมีการทำงานได้เร็วไหม? ความเร็วเท่าไร? ที่จำนวน Request แต่ละชุด (Load Testing)</li><li>ถ้าระบบทำงานหนักๆ ติดต่อกันนาน จะเกิดปัญหาไหม? (Endurance Testing)</li><li>ถ้าระบบทำงานหนักมากๆ จนล่ม สามารถกลับมาทำงานได้ไหม? ใช้เวลากลับมา นานแค่ไหน? (Recovery Testing)</li><li>ถ้าระบบทำงานสูงขึ้นเรื่อยๆ แบบเกินปกติ จะรองรับได้ที่เท่าไร? (Stress Testing)</li><li>ถ้าระบบมีการใช้งานพุ่งสูงแบบกระทันหัน จะเกิดปัญหาไหม? (Spike Testing)</li></ul>



<p>จริงๆ มีมากกว่านี้ แต่จากรายการข้างต้น เรียกว่าเป็นกลุ่มของ Non-Functional Testing ที่ไม่ได้เห็น Bug ชัดเจนจากการเขียนโปรแกรมที่ผิดพลาด จึงอาจต้องอาศัยคนหรือเครื่องมือเพื่อจำลองสถานการณ์ขึ้นมา ว่าได้ตามเกณฑ์ที่กำหนดหรือเปล่า</p>



<h2 class="wp-block-heading">รู้จักกับ k6 &#8211; Open source load testing tool</h2>



<p><a href="https://k6.io/">k6</a> เป็นเครื่องมือ Open source ที่เขียนด้วยภาษา Go สำหรับทำ Load Testing โดยทำคำสั่งผ่าน CLI คล้ายกับ <a href="http://httpd.apache.org/docs/2.4/programs/ab.html">ab (ApacheBench)</a> แต่ด้วยความที่มันเป็น Scriptable tools เลยทำให้สามารถเขียนโค้ดทดสอบเพิ่มเติมได้ โดยใช้ภาษา Javascript  และแน่นอน มันจึงทำ Automated Testing ได้สะดวกขึ้น และน่าจะถูกใจชาว Developer ด้วย</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1256" height="486" src="https://myifew.com/wp-content/uploads/2020/04/k6-sample-api-test.png" alt="" class="wp-image-5670"/></figure>



<p><strong>อธิบายเพิ่มเติม:</strong> <a href="http://httpd.apache.org/docs/2.4/programs/ab.html">ab (ApacheBench)</a> เป็นเครื่องมือประเภท Non-Scriptable ข้อดีคือใช้งานง่าย เพียงพิมพ์คำสั่งและตามด้วย parameter ที่กำหนด ก็ใช้งานได้เลย เหมาะกับคนทั่วไปที่ไม่ต้องเขียนโค้ดเป็น แต่ข้อเสียคือ ไม่สามารถทำอะไรได้นอกเหนือจาก parameter ที่มีให้ ตัวอย่างเช่น</p>



<pre class="wp-block-code"><code>ab -n 100 -c 10 http://www.website.com/ -H "clientId:1234" -H  "token:a2ds5mvo93mcnsk3ncsju3nxdl"</code></pre>



<p>ส่วนเครื่องมือที่นิยมอีกตัวหนึ่ง คือ <a href="https://jmeter.apache.org/">Apache jMeter</a> ที่สามารถเขียนคำสั่งได้ด้วย XML แต่ก็ต้องทำภายใต้ข้อจำกัดของ XML Syntax ที่เขาเตรียมไว้ให้</p>



<h2 class="wp-block-heading">วิธีติดตั้ง k6</h2>



<p>k6 รองรับการใช้งาน 3 ระบบ เลือกติดตั้งตามความเหมาะสมได้เลยครับ</p>



<h4 class="wp-block-heading">สำหรับชาว Linux (deb and rpm packages)</h4>



<pre class="wp-block-code"><code>sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 379CE192D401AB61
echo "deb https://dl.bintray.com/loadimpact/deb stable main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install k6</code></pre>



<h4 class="wp-block-heading" id="windows-msi-installer">สำหรับชาว Mac (brew)</h4>



<pre class="wp-block-code"><code>brew install k6</code></pre>



<h4 class="wp-block-heading" id="windows-msi-installer">สำหรับชาว Windows (MSI installer)</h4>



<p>ไปโหลดได้ที่:&nbsp;<a href="https://dl.bintray.com/loadimpact/windows/k6-v0.26.1-amd64.msi">https://dl.bintray.com/loadimpact/windows/k6-v0.26.1-amd64.msi</a><br>หรือเข้าไปดู release ล่าสุดได้ที่ <a href="https://github.com/loadimpact/k6/releases">https://github.com/loadimpact/k6/releases</a></p>



<h4 class="wp-block-heading">ติดตั้งใช้งานผ่าน Docker</h4>



<pre class="wp-block-code"><code>docker pull loadimpact/k6</code></pre>



<h2 class="wp-block-heading">เริ่มต้นทดสอบ Load Testing ด้วย k6 อย่างง่าย</h2>



<p>ลองมาทดสอบด้วยการส่ง Request ไปหาเว็บไซต์ <a href="http://test.k6.io">http://test.k6.io</a> กัน โดยการสร้างไฟล์ k6-script.js ขึ้นมา และใส่โค้ดไปดังนี้</p>



<pre class="wp-block-code"><code>import http from 'k6/http';
import { sleep } from 'k6';

export default function() {
  http.get('http://test.k6.io');
  sleep(1);
}</code></pre>



<p>จากนั้นทำการ run ชุดโค้ดทดสอบด้วยคำสั่ง ดังนี้</p>



<pre class="wp-block-code"><code>k6 run k6-script.js</code></pre>



<p>จะได้ผลลัพธ์ออกมาแบบนี้ครับ</p>



<figure class="wp-block-image size-large"><img decoding="async" width="2020" height="938" src="https://myifew.com/wp-content/uploads/2020/04/k6-sample-load-web.png" alt="" class="wp-image-5674"/></figure>



<p>โดยที่ค่าสำคัญๆ ที่เราจะใช้ดู คือ</p>



<ul class="wp-block-list"><li><strong>duration</strong> : เวลาที่จะใช้ทดสอบ (ในที่นี้ไม่ได้ระบุ จึงไม่ได้ใช้)</li><li><strong>iterations</strong> : จำนวนครั้ง request ที่ใช้ทดสอบ (ในที่นี้ไม่ได้ระบุ จึงเป็นค่า 1)</li><li><strong>vus</strong> : ย่อมาจาก virtual user หรือการจำลองคนใช้งาน 1 คน (ในที่นี้ไม่ได้ระบุ จึงเป็นค่า 1)</li><li><strong>max</strong> : คือจำนวน vus มากที่สุดที่จะใช้ทดสอบ โดยจะใช้ระบุคู่กับ duration เท่านั้น (ในที่นี้ไม่ได้ระบุ จึงเป็นค่า 1) และในการทำ stage จะใช้ชื่อว่า <strong>target</strong></li><li><strong>data_received</strong> : จำนวน Byte ที่มีการรับกลับมาจากการทดสอบ</li><li><strong>data_sent</strong> : จำนวน Byte ที่มีการส่งออกไปเพื่อทดสอบ</li><li><strong>http_req_duration</strong> : จำนวนเวลารวมที่มีการ request ทดสอบ (ผลรวมของ  http_req_sending + http_req_waiting + http_req_receiving)</li><li><strong>http_reqs</strong> : จำนวนครั้งที่มี request ในช่วงเวลา duration ที่กำหนด</li></ul>



<p>ส่วนค่าอื่นๆ อ่านคำอธิบายได้จากที่นี่ครับ <a href="https://k6.io/docs/getting-started/results-output">https://k6.io/docs/getting-started/results-output</a></p>



<h2 class="wp-block-heading">ลองใส่ k6 Parameters ง่ายๆ เพื่อกำหนดรูปแบบการทดสอบ</h2>



<p>กำหนดให้ vus เป็น 10 และ duration time เป็น 30 วินาที</p>



<pre class="wp-block-code"><code>k6 run --vus 10 --duration 30s k6-script.js</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="2026" height="934" src="https://myifew.com/wp-content/uploads/2020/04/k6-sample-test-vus-duration.png" alt="" class="wp-image-5675"/></figure>



<p>กำหนดให้ vus เป็น 10 และขยับขึ้นไปที่ 20 ภายในเวลา 30 วินาที</p>



<pre class="wp-block-code"><code>k6 run --vus 10 --duration 30s --max 20 k6-script.js</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="2018" height="938" src="https://myifew.com/wp-content/uploads/2020/04/k6-sample-test-vus-duration-max.png" alt="" class="wp-image-5678"/></figure>



<p>กำหนดให้ vus เป็น 10 และ iteration เป็น 100 ครั้ง (หมายถึง 1 vus ทำการ request 10 ครั้ง)</p>



<pre class="wp-block-code"><code>k6 run --vus 10 --iterations 100 k6-script.js</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="2022" height="930" src="https://myifew.com/wp-content/uploads/2020/04/k6-sample-test-vus-iterations.png" alt="" class="wp-image-5676"/></figure>



<p>ข้อมูล Parameters ต่างๆ สามารถดูเพิ่มเติมได้ที่นี่ครับ <a href="https://k6.io/docs/using-k6/options">https://k6.io/docs/using-k6/options</a></p>



<h2 class="wp-block-heading">เปลี่ยนจากการระบุ Parameters รูปแบบการทดสอบ มาเป็นเขียนโค้ด</h2>



<p>parameter ต่างๆ เราสามาถเขียนในรูปแบบโค้ด ใน Javascript เราได้ด้วยนะครับ เช่น</p>



<pre class="wp-block-code"><code>import http from 'k6/http';
import { sleep } from 'k6';

export let options = {
  vus: 10,
  iterations: 100,
};

export default function() {
  http.get('http://test.k6.io');
  sleep(1);
}</code></pre>



<p>จากนั้นก็สั่ง run โค้ด แบบไม่ต้องระบุ parameter ก็จะได้ผลลัพธ์เหมือนกัน</p>



<pre class="wp-block-code"><code>k6 run k6-script.js</code></pre>



<p>รูปแบบการใช้งานต่างๆ อ่านได้จากที่นี่ครับ <a href="https://k6.io/docs/getting-started/running-k6">https://k6.io/docs/getting-started/running-k6</a> และสามารถดู Options ต่างๆ ได้ที่นี่ครับ <a href="https://k6.io/docs/using-k6/options">https://k6.io/docs/using-k6/options</a></p>



<h2 class="wp-block-heading">ทดสอบ Load Testing แบบ Stages ด้วยการกำหนดจำนวน vus ให้ขึ้นลงตามระยะเวลาที่กำหนด</h2>



<p>บางทีเราต้องการจำลองการทดสอบจำนวนคนเข้า (vus) ในแต่ละช่วงเวลาไม่เท่ากัน จะขยับขึ้น (ramping up) จะลง (ramping down)  หรือจะขึ้นไปเรื่อยๆ ก็สามารถระบุเป็น Stages ได้ เช่น</p>



<p>ต้องการทดสอบโดยให้ vus มีประมาณจาก 1 ไป 20 vus ภายในเวลา 30 วินาที จากนั้นให้ลดลงมาที่ 10 vus ภายในเวลา 1:30นาที และลดลงเป็น 0 ภายในเวลา 20 วินาที จะเขียนโค้ด ดังนี้</p>



<pre class="wp-block-code"><code>import http from 'k6/http';
import { sleep } from 'k6';

export let options = {
  stages: [
    { duration: '30s', target: 20 },
    { duration: '1m30s', target: 10 },
    { duration: '20s', target: 0 },
  ],
};

export default function() {
  http.get('http://test.k6.io');
  sleep(1);
}</code></pre>



<p>ผลลัพธ์ที่ได้คือ ทดสอบจำนวน 2:20 นาที มี requests ได้ถึง 1,394 ครั้ง</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="2022" height="936" src="https://myifew.com/wp-content/uploads/2020/04/k6-load-testing-stages.png" alt="" class="wp-image-5677"/></figure>



<h2 class="wp-block-heading">ทดสอบส่งค่าผ่าน HTTP Request และทำการเช็คผลลัพธ์ที่ได้</h2>



<p>ได้ลอง Get data ไปแล้ว คราวนี้มาลองส่ง Input data ผ่าน Post บ้าง และระบุ Header ด้วย จากนั้นจะต้องได้ผลลัพธ์ตามที่เรากำหนด ซึ่งจะมีรูปแบบการเขียนดังนี้</p>



<pre class="wp-block-code"><code>import { check } from "k6";
import http from 'k6/http';

export default function() {
  var url = 'http://test.loadimpact.com/login.php';
  var formdata = {
    login: 'admin',
    password: '123',
  };

  var params = {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    redirects: 1
  };

  let res = http.post(url, formdata, params);
  let jar = http.cookieJar();
  let cookies = jar.cookiesForURL(url);

  check(res, {
    "is status 200": r => r.status === 200,
    "has cookie 'sid'": (r) => cookies.sid.length > 0,
    "has cookie 'uid'": (r) => cookies.uid.length > 0,
    "cookie 'sid' has correct value": (r) => cookies.sid == "39b77ac6-39c4-4c43-98b3-6b2816682036",
    "cookie 'uid' has correct value": (r) => cookies.uid == "3221"
 });

}</code></pre>



<p>ผลลัพธ์ที่ได้คือ</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="2024" height="1132" src="https://myifew.com/wp-content/uploads/2020/04/k6-load-testing-http.png" alt="" class="wp-image-5679"/></figure>



<p>ในตัวอย่าง ผมได้ทดสอบการ login เข้าสู่ระบบ โดยส่ง login, password ผ่าน form data ไปให้ url จากนั้น ทำการตรวจสอบความถูกต้อง 5 เรื่อง คือ</p>



<ul class="wp-block-list"><li>ได้ HTTP Status Codes คือกลับมาเป็น 200 หรือไม่</li><li>มี Cookie ชื่อ sid หรือไม่</li><li>มี Cookie ชื่อ uid หรือไม่</li><li>Cookie ชื่อ sid มีค่าที่ต้องการหรือไม่</li><li>Cookie ชื่อ uid มีค่าที่ต้องการหรือไม่</li></ul>



<p>ซึ่ง จากผลลัพธ์ สามารถเรียกใช้งานได้ และมีความถูกต้อง 5 เรื่อง ข้างต้นด้วย</p>



<p>ซึ่งถ้าผมอยากทำ Load Testing ระบบ login นี้ด้วยการจำลองสัก 10 vus จำนวน 100 ครั้ง ก็ใช้คำสั่งที่เราเคยลองทำมาคือ</p>



<pre class="wp-block-code"><code>k6 run --vus 10 --iterations 100 k6-script-http.js </code></pre>



<h2 class="wp-block-heading">สรุป</h2>



<p>จากที่ได้ลองเล่น k6 ดู ผมชอบตรงที่สามารถเขียนโค้ดการทดสอบได้ (Scriptable) และเขียนด้วยภาษา Javascript ที่นักพัฒนาเว็บไซต์ในโลกส่วนใหญ่มักจะเขียนเป็นกันอยู่แล้ว รวมไปถึง ตัว k6 เอง ใช้ภาษา Go ที่มีความสามารถในการทำงานที่เร็วและไม่กิน Memory มากนัก คิดว่าต่อไปคงได้เปลี่ยนจาก ApacheBench มาใช้ k6 แทน อย่างไม่ต้องสงสัยเลยครับ </p>



<p>ใครสนใจ สามารถไปดูข้อมูลเพิ่มเติมต่อได้ที่ <a href="https://k6.io/">https://k6.io/</a></p>



<p>ใครอยากได้ Demo ที่ผมทดสอบ หาได้จากที่นี่ครับ <a rel="noreferrer noopener" href="https://github.com/ifew/k6-load-testing" target="_blank">https://github.com/ifew/k6-load-testing</a></p>



<p>ส่วนใครอยากดูผลการ Benchmark ทดสอบเครื่องมือ Load Tesing สามารถดูได้ที่ <a href="https://k6.io/blog/comparing-best-open-source-load-testing-tools">https://k6.io/blog/comparing-best-open-source-load-testing-tools</a> (ดูข้อมูลและกราฟทดสอบก็พอ อย่าไปเชื่อผลสรุปมันมาก เพราะค่อนข้างลำเอียง อารมณ์ล้วนๆ จากคนเขียน k6 เอง ฮ่าๆ)</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1678" height="858" src="https://myifew.com/wp-content/uploads/2020/04/k6-MemoryPerRequest.png" alt="" class="wp-image-5680"/></figure>



<p>Reference</p>



<ul class="wp-block-list"><li><a href="https://k6.io/">https://k6.io/</a></li><li><a href="https://k6.io/blog/comparing-best-open-source-load-testing-tools/">https://k6.io/blog/comparing-best-open-source-load-testing-tools/</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/5669/k6-load-testing-tool/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>จัดสรรทรัพยากร AWS Lambda อย่างไร ให้ราคาถูกและเร็วที่สุด</title>
		<link>https://myifew.com/5339/how-to-optimize-memory-on-aws-lambda-for-costs-and-fastest/</link>
					<comments>https://myifew.com/5339/how-to-optimize-memory-on-aws-lambda-for-costs-and-fastest/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Thu, 11 Apr 2019 12:08:16 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Performance Test]]></category>
		<category><![CDATA[Serverless]]></category>
		<category><![CDATA[Testing Tools]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=5339</guid>

					<description><![CDATA[เป็นคำถามที่ทุกคนอยากรู้ ว่าจะตั้งค่า Memory ใน AWS Lambda Function อย่างไรให้ราคาถูกสุด แต่ได้ความเร็วที่สุด แบบไม่ใช้ทรัพยากรเว่อร์เกินไป]]></description>
										<content:encoded><![CDATA[
<p>มาจัดเรื่อง AWS Lambda อีกสักโพสต์ (ก่อนที่ผมจะสลับไปเขียนเรื่องท่องเที่ยวบ้าง ฮ่าๆ) ซึ่งครั้งนี้ขอเขียนถึงวิธีการเลือกใช้ทรัพยากร อย่างเช่น Memory ให้เหมาะสมที่สุด ทำงานได้เร็วด้วย และต้องคุ้มค่ากับการจ่ายเงินด้วย </p>



<span id="more-5339"></span>



<p>ใน Slide ของ <a rel="noreferrer noopener" aria-label="Become a Serverless Black Belt (opens in a new tab)" href="https://www.slideshare.net/AmazonWebServices/become-a-serverless-black-belt-optimizing-your-serverless-applications-aws-online-tech-talks" target="_blank">Become a Serverless Black Belt</a> ได้พูดถึงเรื่องการจัดสรรทรัพยากรไว้หลายหน้า และในหน้าปิดท้ายของตอน ได้บอกไว้ว่า </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Dont&#8217;s Guestimate</p></blockquote>



<p>หมายถึง เรื่องพวกนี้ &#8220;อย่าไปเดา&#8221; นะหนู เพราะเราไม่สามารถรู้ได้เลยว่า โค้ดที่เราเขียน ใช้ Memory เท่าไร ดังนั้นจะต้องจัดสรรให้มันเท่าไรถึงจะเพียงพอ ซึ่งถ้าจัดให้มากไป ก็เสียเงินจับจองเมมโมรี่ (Allocated Memory) โดยเปล่าประโยชน์, และถ้าจัดให้น้อยไป ก็ใช้เวลาคำนวณนานขึ้น (Computed Time) ไม่ว่าจะทางใด ก็มีผลกับค่าใช้จ่ายที่เกิดขึ้นทั้งคู่.. ความสนุก Serverless มันอยู่ตรงนี้แหละ!!</p>



<h2 class="wp-block-heading">เลิกเดา แล้วมาคุยกันด้วยข้อมูลดีกว่า</h2>



<p>ใน Slide เรื่องเดียวกัน ได้อ้างถึงเครื่องมือตัวหนึ่ง ชื่อ <a rel="noreferrer noopener" aria-label="AWS Lambda Power Tuning (opens in a new tab)" href="https://github.com/alexcasalboni/aws-lambda-power-tuning" target="_blank">AWS Lambda Power Tuning</a> ที่พัฒนาโดย Alex Casalboni และเขาได้เล่าที่มาในบล็อก <a rel="noreferrer noopener" aria-label="AWS Lambda Power Tuning with AWS Step Functions (opens in a new tab)" href="https://serverless.com/blog/aws-lambda-power-tuning/" target="_blank">AWS Lambda Power Tuning with AWS Step Functions</a> ว่า Serverless Developer ทุกคนมักหลับหูหลับตาเพื่อจัดสรรทรัพยากร หรือไม่ก็ใช้วิธีการ Manual Test เพื่อทดสอบดูทีละแบบ ซึ่งมันก็เสียเวลาและไม่ได้ผลลัพธ์ที่ดีแน่นอน</p>



<p>พี่แกเลยบอกว่า ถ้าเช่นนั้นเรามาใช้วิธี Data-Driven ดีกว่า! แกเลยเริ่มจากทำ<a rel="noreferrer noopener" aria-label="โพลสำรวจใน Twitter (opens in a new tab)" href="https://twitter.com/alex_casalboni/status/854059283465383937" target="_blank">โพลสำรวจใน Twitter</a> ว่าสิ่งที่สังเกตเห็นมันเป็นจริงไหม</p>



<figure class="wp-block-embed-twitter wp-block-embed is-type-rich is-provider-twitter"><div class="wp-block-embed__wrapper">
<blockquote class="twitter-tweet" data-width="550" data-dnt="true"><p lang="en" dir="ltr">How do you choose the optimal RAM configuration for your AWS Lambda Functions? I&#39;ll publish results &amp; my OSS project in a week! <a href="https://twitter.com/hashtag/serverless?src=hash&amp;ref_src=twsrc%5Etfw">#serverless</a></p>&mdash; Alex Casalboni (@alex_casalboni) <a href="https://twitter.com/alex_casalboni/status/854059283465383937?ref_src=twsrc%5Etfw">April 17, 2017</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div></figure>



<p>ซึ่งกว่า 50% ในโพล เคยใช้ Memory เท่าไรก็ตั้งไว้แบบเดิมเท่านั้น ไม่ได้สนใจที่จะ Tuning อะไร และครึ่งหนึ่งนิยมตั้งค่าไว้ที่ 128MB ทุก Function ด้วยเหตุผลที่ว่า เพราะมันราคาถูกที่สุดน่ะสิ! ไม่ได้สนใจเลยว่าจะทำงานได้ไวไหม</p>



<p>แต่ไม่ว่าจะเลือกตอบข้อไหน ก็ยังไม่ใช่สิ่งที่ควรทำในการตั้งค่า Memory ให้กับ Serverless อย่าง AWS Lambda</p>



<p>จากนั้นเขาก็เขียนเล่าถึงเหตุผลว่าทำไม Function ทำงานได้ช้า และคอนเซปของการแก้ปัญหาของ (ซึ่งถ้าใครอยากอ่านฉบับเต็ม ไปอ่านได้ที่ <a rel="noreferrer noopener" href="https://serverless.com/blog/aws-lambda-power-tuning/" target="_blank">AWS Lambda Power Tuning with AWS Step Functions) </a>จนสรุปได้ว่า การ Tuning Memory ทีละลำดับ พร้อมกับทดสอบเรียกใช้ (Invocating) ด้วยจำนวนที่ต้องการ ​กับ Lambda Function ทีละตัว คือหนทางที่เหมาะสม และต้องเป็นการทดสอบแบบ Automate ทั้งหมดด้วย เพื่อความรวดเร็ว  จึงเป็นที่มาของเครื่องมือ AWS Lambda Power Tuning ที่ผมกำลังจะเขียนถึง</p>



<h2 class="wp-block-heading">รู้จักกับ AWS Lambda Power Tuning</h2>



<p>เจ้าเครื่องมือ AWS Lambda Power Tuning นี้ ถูกพัฒนาด้วย Node.js โดยจะมี Lambda Function จำนวน 4 ตัว และเราต้องสร้าง Role กับ StepFunction เพื่อใช้มัน</p>



<p>แต่ไม่ต้องตกใจ ว่าจะยุ่งยาก เพราะโค้ดบน Github นาย Alex ได้มีไฟล์ Serverless.yml หรือเป็น AWS CloudFormation Script ไว้ให้เราใช้ Provision Infrastructure เรียบร้อย แต่เราจะต้องรันคำสั่งด้วยเครื่องมือชื่อ Serverless</p>



<p>การทำงานของมันคือ มันจะไปสร้าง Version ใน Lambda Function และกำหนด Memory ทีละช่วงที่เราต้องการ และทดสอบทีละ Version โดยจะหาค่าที่เหมาะสมที่สุดว่า ต้องใช้ Memory เท่าไร ที่สามารถ Compute ได้เร็วสุด และจ่ายเงินถูกที่สุด </p>



<p>ถ้าทำเอง น่าจะใช้เวลามากๆ เลยทีเดียว กว่าจะทดสอบ Lambda ได้ทีละตัว</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="648" height="956" src="https://myifew.com/wp-content/uploads/2019/04/lambda-power-tunning-working.png" alt="" class="wp-image-5351"/></figure>



<h2 class="wp-block-heading" id="mce_25">ตัวอย่างผลลัพธ์ของ AWS Lambda Power Tuning</h2>



<p>เช่น ผมมี Lambda Function เพื่อแสดงรายการสินค้า 1 ตัว ผมต้องการรู้ว่า Memory ในช่วง 128 MB &#8211; 1024 MB จำนวนเท่าไรจะเหมาะสมที่สุด..</p>



<p>ตัว AWS Lambda Power Tuning ก็จะเรียก Function ของมันมาเรียงเป็น Step ทำงานให้เราดูเป็นกราฟ</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2142" height="1234" src="https://myifew.com/wp-content/uploads/2019/04/example-lambda-power-tunning.png" alt="" class="wp-image-5349"/></figure>



<p>เมื่อทำการทดสอบเสร็จ จะสรุปที่ Output ด้านขวามือ เพื่อบอกว่า ควรใช้ Power (Memory) เท่าไร ถึงจะคุ้มค่าที่สุด ด้วย Cost และ Duration Time เท่าไร</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2642" height="1250" src="https://myifew.com/wp-content/uploads/2019/04/example-lambda-power-tunning-monitoring-execution-1.png" alt="" class="wp-image-5361"/></figure>



<p>ถ้าใครอยากเห็นรายละเอียดการทดสอบแต่ละ Memory ให้เลื่อนลงมาดูด้านล่าง จะมี Output บอกอีกส่วนหนึ่งแบบละเอียด</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="914" height="1158" src="https://myifew.com/wp-content/uploads/2019/04/example-lambda-power-tunning-logs-detail.png" alt="" class="wp-image-5369"/></figure>



<p>คราวนี้ ทดสอบครั้งแรก ผมไม่ค่อยเชื่อผลเท่าไร จึงลองทดสอบทั้งหมด 4 รอบ, แต่ละรอบและแต่ละ Memory ผมจำลองให้มีการร้องขอ (Invocation) จำนวน 10 ครั้ง จำนวน 3 รอบ และ 100 ครั้ง จำนวน 1 รอบ ผลที่ได้ออกมา คือ</p>



<p><strong>Execution #1 &#8211; Invocation 10</strong></p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="898" height="404" src="https://myifew.com/wp-content/uploads/2019/04/example-compare-lambda-power-tunning-list1.png" alt="" class="wp-image-5346"/></figure>



<p><strong>Execution #2 &#8211; Invocation 10</strong></p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="862" height="408" src="https://myifew.com/wp-content/uploads/2019/04/example-compare-lambda-power-tunning-list3.png" alt="" class="wp-image-5348"/></figure>



<p><strong>Execution #3 &#8211; Invocation 10</strong></p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="860" height="408" src="https://myifew.com/wp-content/uploads/2019/04/example-compare-lambda-power-tunning-list2.png" alt="" class="wp-image-5347"/></figure>



<p><strong>Execution #4 &#8211; Invocation 100</strong></p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="902" height="406" src="https://myifew.com/wp-content/uploads/2019/04/example-compare-lambda-power-tunning-list4.png" alt="" class="wp-image-5350"/></figure>



<p>จากผลการทดสอบ แปลว่า Function แสดงรายการสินค้า ถ้าใช้ Memory ที่ 320 MB จะเร็วและถูกที่สุด โดยเราไม่จำเป็นต้องใช้ Memory ถึง 1024 MB ก็ได้ เพราะผลที่ได้อาจจะไม่ต่างกันมาก ไม่ว่าจะมีการเรียกใช้ 10 ครั้งหรือ 100 ครั้ง ต่อเนื่องก็ตาม </p>



<p>(อย่าลืมว่า ค่าใช้จ่ายการ Compute จะปัดเศษขึ้น เป็นหน่วย 100ms นะครับ ไม่ว่าจะ 40.2ms , 80.8ms ก็ถูกปัดไปคิดเงินเป็น 100ms เท่ากัน)</p>



<p>ปล. จุดสังเกต คือ Memory 256 MB จะทำงานได้ช้ากว่า และแพงกว่า ทั้ง 4 รอบเลย ตรงนี้ผมต้องไปตรวจสอบในระดับ Source Code, Logs, หรือใช้ AWS X-Ray ดูต่อว่าทำไม</p>



<h2 class="wp-block-heading" id="mce_57">วิธีการติดตั้ง AWS Lambda Power Tuning ผ่าน Serverless</h2>



<p class="has-background has-very-light-gray-background-color">** หากใครไม่สะดวกติดตั้งผ่าน Serverless สามารถทำด้วยการ Clone git แล้วรันสคริ้ป ซึ่งสามารถดูได้ที่ <a href="https://github.com/alexcasalboni/aws-lambda-power-tuning">https://github.com/alexcasalboni/aws-lambda-power-tuning</a> **</p>



<p>ขายของมานาน มาดูวิธีติดตั้งและใช้งานกัน ซึ่งในที่นี้ผมยกตัวอย่างของ MacOS, Linux  ส่วนชาว Windows ให้ใช้ PowerShell ดูนะครับ</p>



<h4 class="wp-block-heading">ความต้องการก่อนติดตั้งใช้งาน</h4>



<ol class="wp-block-list"><li>AWS Account จะต้องมีสิทธิ์ใช้งาน ดังนี้<ul><li>cloudformation:*</li><li>states:*</li><li>lambda:*</li><li>iam:CreateRole</li></ul></li><li>เครื่องที่ติดตั้งจะต้องมี npm (<a rel="noreferrer noopener" aria-label="วิธีติดตั้ง (opens in a new tab)" href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" target="_blank">วิธีติดตั้ง npm</a>)</li></ol>



<h4 class="wp-block-heading">ติดตั้ง Serverless Framework และใส่ AWS credentials</h4>



<pre class="wp-block-code"><code>$ npm install serverless -g
$ serverless config credentials --provider aws --key XXX --secret YYY</code></pre>



<h4 class="wp-block-heading">ติดตั้ง AWS Lambda Power Tuning</h4>



<pre class="wp-block-code"><code>$ serverless install -u https://github.com/alexcasalboni/aws-lambda-power-tuning</code></pre>



<h4 class="wp-block-heading">ทำการติดตั้ง Package Dependency</h4>



<pre class="wp-block-code"><code>$ cd aws-lambda-power-tuning
$ npm install</code></pre>



<h4 class="wp-block-heading">สร้าง Config ของ State Machine ในไฟล์ serverless.yml</h4>



<pre class="wp-block-code"><code>$ npm run generate -- -A ACCOUNT_ID [-R eu-west-1] [-P 128,256,512,1024]

เช่น

$ npm run generate -- -A 182000046000 -R ap-southeast-1 -P 128,192,256,320,448,512,704,1024</code></pre>



<h4 class="wp-block-heading">ทำการ Deploy AWS Lambda Power Tuning</h4>



<pre class="wp-block-code"><code>$ serverless deploy</code></pre>



<h2 class="wp-block-heading" id="mce_66">วิธีการใช้งาน AWS Lambda Power Tuning</h2>



<p>เมื่อติดตั้งเสร็จแล้ว ลองเช็คที่ AWS Lambda Function เรา จะเจอฟังก์ชั่นเพิ่มขึ้นมา ดังนี้</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2582" height="340" src="https://myifew.com/wp-content/uploads/2019/04/lambda-power-tunning-lambda-function.png" alt="" class="wp-image-5354"/></figure>



<p>จากนั้นให้ไปดูที่เซอร์วิส <a rel="noreferrer noopener" aria-label="Step Function (opens in a new tab)" href="https://console.aws.amazon.com/states/home" target="_blank">Step Function</a> จะพบ State Machine</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2790" height="714" src="https://myifew.com/wp-content/uploads/2019/04/lambda-power-tuning-state-machine.png" alt="" class="wp-image-5355"/></figure>



<p>ให้กดที่ Start Excution</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2130" height="968" src="https://myifew.com/wp-content/uploads/2019/04/lambda-power-tuning-state-machine-execute.png" alt="" class="wp-image-5356"/></figure>



<p>กรอกข้อมูล State Machine Input สำหรับจะใช้ทำงาน โดยมีรูปแบบตามนี้</p>



<pre class="wp-block-code"><code>{
    "lambdaARN": "your-lambda-function-arn",
    "num": 10
}</code></pre>



<p>เช่น</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2502" height="870" src="https://myifew.com/wp-content/uploads/2019/04/lambda-power-tuning-state-machine-execute-input-1.png" alt="" class="wp-image-5358"/></figure>



<p>รอสักครู่ จะมี Status บอกเราว่า Successed พร้อมบอกรายละเอียดการทำงาน และผลลัพธ์ ซึ่งถ้ามันขึ้นว่า Failed ให้เราไปดูที่ Exception ได้ </p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2642" height="1250" src="https://myifew.com/wp-content/uploads/2019/04/example-lambda-power-tunning-monitoring-execution-1.png" alt="" class="wp-image-5361"/></figure>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2606" height="1256" src="https://myifew.com/wp-content/uploads/2019/04/example-lambda-power-tunning-monitoring-execution-detail.png" alt="" class="wp-image-5360"/></figure>



<h2 class="wp-block-heading">การกำหนดค่า State Machine Input</h2>



<p>เราสามารถกำหนด parameters ของ input ได้ ดังนี้:</p>



<ul class="wp-block-list"><li><strong>lambdaARN</strong> (จำเป็น): ARN ของ Lambda Function ที่ต้องการทดสอบ</li><li><strong>num</strong> (จำเป็น): หมายเลขจำนวนที่ต้องการทดสอบเรียกใช้งาน (invocations) ต่อครั้งและต่อ Memory ที่เรากำหนด (อย่างน้อย 5, แนะนำ: 10 &#8211; 100)</li><li><strong>payload</strong> (string/object): Input สำหรับใช้ใน Lambda Function ที่ต้องการทดสอบ (ใส่เป็นข้อมูล JSON)</li><li><strong>parallelInvocation</strong> (ค่าตั้งต้น: false): ถ้าเราใส่เป็น true, จะมีการเรียก Execute พร้อมๆ กัน ตามจำนวนที่เราระบุใน num</li></ul>



<h2 class="wp-block-heading">สรุป</h2>



<p>ไม่ยากเลยใช่ไหมครับ สามารถเอาไปใช้ตรวจสอบ AWS Lambda Fucntion ของเราเองได้อย่างรวดเร็วและสะดวก ไม่ต้องทำมือเองท่ีละตัว หรือใช้วิธีการเดา เพื่อความรวดเร็ว และคุ้มค่าที่สุด</p>



<p><strong>อ้างอิง</strong></p>



<ul class="wp-block-list"><li><a href="https://serverless.com/blog/aws-lambda-power-tuning/">https://serverless.com/blog/aws-lambda-power-tuning/</a></li><li><a rel="noreferrer noopener" aria-label="https://github.com/alexcasalboni/aws-lambda-power-tuning (opens in a new tab)" href="https://github.com/alexcasalboni/aws-lambda-power-tuning" target="_blank">https://github.com/alexcasalboni/aws-lambda-power-tuning</a></li><li><a rel="noreferrer noopener" aria-label="https://www.slideshare.net/AmazonWebServices/become-a-serverless-black-belt-optimizing-your-serverless-applications-aws-online-tech-talks (opens in a new tab)" href="https://www.slideshare.net/AmazonWebServices/become-a-serverless-black-belt-optimizing-your-serverless-applications-aws-online-tech-talks" target="_blank">https://www.slideshare.net/AmazonWebServices/become-a-serverless-black-belt-optimizing-your-serverless-applications-aws-online-tech-talks</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/5339/how-to-optimize-memory-on-aws-lambda-for-costs-and-fastest/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ทดสอบ AWS Lambda Function บนเครื่องตัวเอง ด้วย Lambda Docker</title>
		<link>https://myifew.com/5257/how-to-test-aws-lambda-on-local-machine-via-lambda-docker/</link>
					<comments>https://myifew.com/5257/how-to-test-aws-lambda-on-local-machine-via-lambda-docker/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Thu, 21 Feb 2019 16:25:07 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.Net Core]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Serverless]]></category>
		<category><![CDATA[Testing Tools]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=5257</guid>

					<description><![CDATA[จากที่เคยนำเสนอเครื่องมือตัวหนึ่งไปแล้วในบล็อก ทดสอบ .NET AWS Lambda ด้วย AWS .NET Mock Lambda Test Tool แต่ยังไม่หนำใจ เพราะผมพบว่ามันมีปัญหากับโค้ดที่เขียนแบบ Dependency Injection ซึ่งลองหาวิธี Debug&#8230;]]></description>
										<content:encoded><![CDATA[
<p>จากที่เคยนำเสนอเครื่องมือตัวหนึ่งไปแล้วในบล็อก <a href="https://myifew.com/5223/test-netcore-aws-lambda-by-aws-net-mock-lambda-test-tool/">ทดสอบ .NET AWS Lambda ด้วย AWS .NET Mock Lambda Test Tool</a> แต่ยังไม่หนำใจ เพราะผมพบว่ามันมีปัญหากับโค้ดที่เขียนแบบ Dependency Injection ซึ่งลองหาวิธี Debug แต่ก็ยังไม่เห็นอะไร เลยตัดใจลองหาเครื่องมือตัวอื่นดู ก็เจอ <a rel="noreferrer noopener" aria-label="AWS SAM (AWS Serverless Application Model) (opens in a new tab)" href="https://aws.amazon.com/serverless/sam/" target="_blank">AWS SAM (AWS Serverless Application Model)</a> </p>



<p>แต่ก็กระนั้นอีก ในหน้าเว็บโปรเจ็คบอกทำงานกับ .NET Core 2.1 ได้ แต่พอลองทำดู กลับบอกว่า ไม่รองรับ .NET Core Runtime!! (ใครแก้ปัญหาสองข้อบนของผมได้ มาแลกเปลี่ยนความรู้กันหน่อยครับ จักหายคาใจ) ก็เลยต้องแกะมัน พบว่า มันไปใช้ Lambda Docker เพื่อสร้าง Environment จำลองขึ้นมาสำหรับทดสอบ.. ปั๊ดโธ่ว แบบนี้ก็เสร็จโก๋!!  จึงเป็นที่มาของบล็อกนี้..</p>



<span id="more-5257"></span>



<p style="text-align:center" class="has-background has-very-light-gray-background-color"><strong>คำแนะนำ: ผู้อ่านบล็อกนี้ควรใช้งาน AWS Lambda และ Docker เบื้องต้นแล้ว,&nbsp;ตัวอย่างใช้เป็น&nbsp;.NET&nbsp;Core 2.1&nbsp;แต่สามารถนำวิธีใช้กับภาษาอื่นๆได้</strong></p>



<h2 class="wp-block-heading"> Lambda Docker คืออะไร? ดีไหม?</h2>



<p><g class="gr_ gr_24 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Grammar only-ins doubleReplace replaceWithoutSep" id="24" data-gr-id="24">เป็น</g>&nbsp;Docker ที่จำลอง Environment ไว้เพื่อทดสอบ (Sandbox) ของ&nbsp;<a href="https://aws.amazon.com/lambda/">AWS Lambda</a>&nbsp;ซึ่งเคลมตัวเองว่า ใกล้เคียงกับของจริงมากๆ</p>



<p>ถามว่าใกล้เคียงขนาดไหน? คำตอบคือใกล้มากจริงๆ ตามที่เขาโม้ไว้ เพราะภายใน image ของมันประกอบไปด้วย software, libraries, โครงสร้างของไฟล์ และ permissions, environment variables, context objects หรือแม้แต่  user สำหรับใช้เรียก process ก็ยังใช้ชื่อเดียวกัน</p>



<p>ด้วยความเหมือนเป๊ะ มันจึงเหมาะที่จะเอา Lambda Function มาทดสอบบน Docker Environment ที่มีข้อจำกัดคล้ายกับ AWS Lambda ได้เกือบ 100%, และที่สำคัญ มันปรับ Memory, Timeout และใช้ Layer ได้ด้วยนะ </p>



<p>มีข้อดีแล้วก็ต้องมีข้อเสีย ซึ่งตอนนี้ผมพบจุดเดียว คือ เรื่องของเวลาในการคำนวณ ซึ่งเอาไปอ้างอิงไม่ได้ เพราะไม่มี Cold Start และมันเป็น CPU บนเครื่องเรา, ถ้าจำทดสอบเพื่อไปคำนวณค่าใช้จ่าย ควรใช้เครื่องมืออีกตัวชื่อว่า <a rel="noreferrer noopener" aria-label="AWS Lambda Power Tuning (opens in a new tab)" href="https://github.com/alexcasalboni/aws-lambda-power-tuning" target="_blank">AWS Lambda Power Tuning</a> (ไว้จะเขียนถึงอีกที)</p>



<h2 class="wp-block-heading">สิ่งที่ต้องติดตั้งก่อนใช้ Lambda Docker </h2>



<p>ก่อนไปต่อ ควรติดตั้ง <a rel="noreferrer noopener" aria-label="Docker (opens in a new tab)" href="https://www.docker.com/get-started" target="_blank">Docker</a> ซะก่อนนะ (เช็คให้เรียบร้อยว่าไม่ติด Security Policy ทำงานได้ดี สามารถ Pull Image และ Run Container ได้)</p>



<h2 class="wp-block-heading">เริ่มต้นใช้งาน Lambda Docker</h2>



<p>รูปแบบของคำสั่งจะเป็นดังนี้</p>



<pre class="wp-block-code"><code>docker run [--rm] -v &lt;code_dir>:/var/task [-v &lt;layer_dir>:/opt] lambci/lambda:&lt;runtime> [&lt;handler>] [&lt;event>]</code></pre>



<p>การทำงานของมันคือ จะสร้าง Docker Container ขึ้นมา และเอาโค้ดของเราไปรันทดสอบ ด้วยตัวแปรต่างๆที่เราระบุไว้ใน Command แค่นั้นเอง</p>



<ul class="wp-block-list"><li><strong>&#8211;rm</strong> คือเพื่อให้สร้าง Container มาทดสอบเพียงครั้งเดียว และทำลายตัวเองทิ้ง (ไม่ใส่ก็ได้ รันทำงานซ้ำไปได้เรื่อยๆ)</li><li><strong> -v &lt;code_dir&gt;:/var/task</strong> คือ ชี้ที่อยู่ของโค้ดเรา ไปให้ตรงกับโฟลเดอร์ใน Container เพื่อใช้งาน</li><li> <strong>-v &lt;layer_dir&gt;:/opt</strong> คือ ชี้ที่อยู่ของ layer  โค้ด ไปให้ตรงกับโฟลเดอร์ใน Container เพื่อใช้งาน (ถ้าไม่รู้จัก หรือไม่ได้ใช้ ก็ไม่ต้องใส่)</li><li><strong>&lt;runtime&gt;</strong> &nbsp;คือ Runtime Language ที่เราใช้เขียน Function เช่น dotnetcore2.1, nodejs4.3, python3.7, java8, go1.x</li><li><strong>&lt;handler&gt;</strong> คือ Fucntion Handler </li><li><strong>&lt;event&gt;</strong> คือ Request Input นั่นหละ</li></ul>



<h2 class="wp-block-heading">ทดสอบรันคำสั่งง่ายๆ</h2>



<p>ตัวอย่าง Function ของผมชื่อ aws_lambda_function โดยรับ string เข้าไป จากนั้นจะพ่นออกมาว่า &#8220;Hello, &lt;ชื่อ&gt;&#8221; โดยมีรูปแบบคำสั่งคือ</p>



<pre class="wp-block-code"><code>docker run --rm -v "$PWD":/var/task lambci/lambda:dotnetcore2.1 aws-lambda-function::aws_lambda_function.Function::FunctionHandler '"iFew"'</code></pre>



<p>เนื่องด้วยการทำงานมันจะ run code ที่ผ่านการ complie แล้ว, ซึ่งถ้าให้แน่ใจ ว่าไม่ได้รันอยู่บนโค้ดชุดเดิม ให้เราทำคำสั่ง compile ก่อนสักครั้ง จากนั้นไปที่โฟลเดอร์โค้ดที่ Compiled และทำคำสั่งด้านบนอีกที (ผมชี้ที่อยู่โค้ดไปที่ $PWD หมายถึง ให้ใช้โค้ดในโฟลเดอร์ปัจจุบันที่ผมอยู่)</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="132" src="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-1-1200x132.png" alt="" class="wp-image-5266" srcset="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-1-1200x132.png 1200w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-1-1024x112.png 1024w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-1-768x84.png 768w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-1-700x77.png 700w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-1-600x66.png 600w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-1.png 2104w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<p>ผลลัพธ์ที่ได้</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="93" src="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-result-1-1200x93.png" alt="" class="wp-image-5267" srcset="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-result-1-1200x93.png 1200w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-result-1-1024x79.png 1024w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-result-1-768x59.png 768w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-result-1-700x54.png 700w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-result-1-600x46.png 600w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-command-result-1.png 2402w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<h2 class="wp-block-heading" id="mce_51">ทดสอบรันคำสั่งโดยใส่ Environment Variable</h2>



<p>จากตัวอย่างแรก สังเกตว่ามัน Allocate Memory ให้ถึง 1,536MB เลยทีเดียว (เป็น Default ของมัน) ซึ่งผมอยากกำหนดให้ใช้ Memory แค่ 128MB และ Timeout 30 วินาที เพื่อทดสอบการทำงาน ในสภาพแวดใกล้เคียงของจริง ด้วยคำสั่งนี้</p>



<pre class="wp-block-code"><code>docker run --rm -v "$PWD":/var/task -e AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128 -e AWS_LAMBDA_FUNCTION_TIMEOUT=30 lambci/lambda:dotnetcore2.1  aws-lambda-function::aws_lambda_function.Function::FunctionHandler '"iFew"'</code></pre>



<p>ซึ่ง ใช้ parameter ชื่อ -e ของ Docker นั่นหละเป็นตัวกำหนด โดยลัพลัพธ์ที่ได้ คือ</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="95" src="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-env-command-result-1200x95.png" alt="" class="wp-image-5269" srcset="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-env-command-result-1200x95.png 1200w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-env-command-result-1024x81.png 1024w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-env-command-result-768x61.png 768w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-env-command-result-700x55.png 700w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-env-command-result-600x47.png 600w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-env-command-result.png 2684w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<p>สังเกตว่า Memory ตอนนี้จัดสรรให้แค่ 128MB เท่านั้น ส่วน Timoue ยังไม่เห็นผลในตอนนี้เพราะโค้ดง่ายๆ ทำงานไว</p>



<p>ตัว environment ให้ใช้งานต่างๆ ดูเพิ่มเติมได้ที่ https://github.com/lambci/docker-lambda</p>



<h2 class="wp-block-heading">ทดสอบรันคำสั่งโดยอ้างอิงกับ Database ภายนอก</h2>



<p>การใช้งานจริงๆของเรา มันไม่ง่ายเหมือน Function ด้านบนแน่นอน ซึ่งผมเจอปัญหานี้เช่นกัน และใน Document ไม่ได้บอกไว้ว่าทำอย่างไร งมอยู่สักพัก ถึงเจอวิธี โดยการใช้ทำให้ Lambda Docker ของเราอยู่ในวง Network เดียวกับ Docker Database ที่ผมมีซะ (พอดีผมใช้ MySQL บน Docker, ถ้าใครใช้ MySQL เข้าใจว่าสามารถใช้งานได้เลย เนื่องจาก network เป็นแบบ bridge ที่ทำให้ Container เราต่ออินเทอร์เน็ตหรือวง Network ในเครื่องเราได้อยู่แล้ว)</p>



<p>ลองดูตัวอย่างคำสั่งนี้ครับ</p>



<pre class="wp-block-code"><code>docker run --rm -v "$PWD":/var/task --network mysql -e TEST_LAMBDA_DBCONNECTION="server=mysql;userid=root;password=1234;database=test_lambda;convert zero datetime=True; CharSet=utf8" -e AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128 lambci/lambda:dotnetcore2.1 list_profile::list_profile.Function::Get</code></pre>



<p>จะสังเกตว่ามีตัวแปรแปลกๆมานิดนึง คือ &#8211;network mysql หมายถึง ให้ Container นี้อยู่ในวง Network ชื่อ mysql โดยในวงนั้นผมมี Container MySQL อยู่ในนั้นอยู่แล้ว</p>



<p>จากนั้นผมระบุ Environment Variable ชื่อว่า TEST_LAMBDA_DBCONNECTION เข้าไป เนื่องจากโค้ดของผมเรียกใช้ config ผ่าน Environment Variable (ตาม<a rel="noreferrer noopener" aria-label="หลักการข้อ 3 ใน The Twelve Factor (opens in a new tab)" href="https://12factor.net/config" target="_blank">หลักการข้อ 3. Config ใน The Twelve Factor</a>)</p>



<p>ผลลัพธ์ที่ได้คือ</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="117" src="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-mysql-command-result-1200x117.png" alt="" class="wp-image-5270" srcset="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-mysql-command-result-1200x117.png 1200w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-mysql-command-result-1024x100.png 1024w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-mysql-command-result-768x75.png 768w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-mysql-command-result-700x68.png 700w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-mysql-command-result-600x59.png 600w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-basic-mysql-command-result.png 2680w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<h4 class="wp-block-heading">แถมนิดนึง วิธีการสร้าง Docker Network</h4>



<p>คำสั่งง่ายๆ คือ</p>



<pre class="wp-block-code"><code>docket create network &lt;ชื่อnetworkที่ต้องการ></code></pre>



<p>แค่นี้ก็จะได้วง Network มาแล้วครับ โดยในตัวอย่างผมใช้ชื่อวงว่า mysql</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="976" height="226" src="https://myifew.com/wp-content/uploads/2019/02/lambda-docket-network-2.png" alt="" class="wp-image-5274" srcset="https://myifew.com/wp-content/uploads/2019/02/lambda-docket-network-2.png 976w, https://myifew.com/wp-content/uploads/2019/02/lambda-docket-network-2-768x178.png 768w, https://myifew.com/wp-content/uploads/2019/02/lambda-docket-network-2-700x162.png 700w, https://myifew.com/wp-content/uploads/2019/02/lambda-docket-network-2-600x139.png 600w" sizes="auto, (max-width: 976px) 100vw, 976px" /></figure>



<p>ดังนั้น หากเรามี Container อยู่แล้ว ให้เพิ่มเข้าวง Network ด้วยคำสั่ง</p>



<pre class="wp-block-code"><code>docker network connect &lt;ชื่อnetwork> &lt;ชื่อcontainer></code></pre>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="98" src="https://myifew.com/wp-content/uploads/2019/02/lambda-docket-create-network-1200x98.png" alt="" class="wp-image-5273" srcset="https://myifew.com/wp-content/uploads/2019/02/lambda-docket-create-network-1200x98.png 1200w, https://myifew.com/wp-content/uploads/2019/02/lambda-docket-create-network-1024x83.png 1024w, https://myifew.com/wp-content/uploads/2019/02/lambda-docket-create-network-768x63.png 768w, https://myifew.com/wp-content/uploads/2019/02/lambda-docket-create-network-700x57.png 700w, https://myifew.com/wp-content/uploads/2019/02/lambda-docket-create-network-600x49.png 600w, https://myifew.com/wp-content/uploads/2019/02/lambda-docket-create-network.png 2134w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<h2 class="wp-block-heading" id="mce_69">ทดสอบรันคำสั่งโดยส่ง Request Input ด้วย APIGatewayProxy (หรือรันคำสั่งแบบมี JSON  Input ยาวๆ)</h2>



<p>โดยปกติผมจะใช้ AWS API Gateway อยู่แล้ว ดังนั้นตัว Request Input ผมจะชอบใช้ในรูปแบบของ API Gateway Proxy Request เพราะมันสามารถส่ง Request Input ได้ทั้งแบบ Path Parameter, Query String, Header, Body ซึ่งลดควมซับซ้อน ไม่ต้องไปทำการ Mapping Input Data อะไรให้ยุ่งยากใน AWS API Gateway ซึ่งถ้าคุณใช้เหมือนกัน ก็สามารถเอาตัวอย่างนี้ไปทดสอบกับ Lambda Docker ได้ครับ</p>



<p>โดยตัว API Gateway Proxy Request เนื้อมันจริงๆคือ JSON ที่ AWS API Gateway รับเข้าไป จากนั้นมันจะกระทำการ Mapping นั่นโน่นนี่ให้เอง และสร้าง Request ตามที่เรากำหนดใน JSON นั้นไปทำงานกับ Function เราอีกที ซึ่งรูปแบบของ JSON มันจะยาวมากๆ ครับ ดังนั้น การส่ง Input ยาวๆ เราสามารถทำได้สามแบบ</p>



<h4 class="wp-block-heading">ในตัวอย่างแรก สามารถใส่ event ต่อท้ายได้ตามรูปแบบมาตรฐานของมันเลยครับ</h4>



<pre class="wp-block-code"><code>docker run --rm -v "$PWD":/var/task --network mysql -e TEST_LAMBDA_DBCONNECTION="server=mysql;userid=root;password=1234;database=test_lambda;convert zero datetime=True; CharSet=utf8" -e AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128 lambci/lambda:dotnetcore2.1 get_profile::get_profile.Function::Get '{"resource":"/{proxy+}","path":"/","httpMethod":"GET","headers":null,"queryStringParameters":null,"pathParameters":{"id":"1"},"stageVariables":null,"requestContext":{"accountId":"AAAAAAAAAAAA","resourceId":"5agfss","stage":"test-invoke-stage","requestId":"test-invoke-request","identity":{"cognitoIdentityPoolId":null,"accountId":"AAAAAAAAAAAA","cognitoIdentityId":null,"caller":"BBBBBBBBBBBB","apiKey":"test-invoke-api-key","sourceIp":"test-invoke-source-ip","cognitoAuthenticationType":null,"cognitoAuthenticationProvider":null,"userArn":"arn:aws:iam::AAAAAAAAAAAA:root","userAgent":"Apache-HttpClient/4.5.x (Java/1.8.0_102)","user":"AAAAAAAAAAAA"},"resourcePath":"/{proxy+}","httpMethod":"GET","apiId":"t2yh6sjnmk"},"body":null}'</code></pre>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="138" src="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-apiproxy-mysql-command-result1-1200x138.png" alt="" class="wp-image-5275" srcset="https://myifew.com/wp-content/uploads/2019/02/lambda-docker-apiproxy-mysql-command-result1-1200x138.png 1200w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-apiproxy-mysql-command-result1-1024x118.png 1024w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-apiproxy-mysql-command-result1-768x89.png 768w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-apiproxy-mysql-command-result1-700x81.png 700w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-apiproxy-mysql-command-result1-600x69.png 600w, https://myifew.com/wp-content/uploads/2019/02/lambda-docker-apiproxy-mysql-command-result1.png 2690w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<h4 class="wp-block-heading">ตัวอย่างสอง สามารถใส่ event ด้านหน้า ในรูปแบบ stdin ได้</h4>



<p>โดยใช้การ echo ค่า JSON ที่เราต้องการส่งออกไป จากนั้นให้ ใส่ | คั่นคำสั่งรัน Container เพื่อรับไปใช้ พร้อมกับระบุ parameter เพิ่มเติมอีกหน่อยคือ</p>



<pre class="wp-block-code"><code>-i -e DOCKER_LAMBDA_USE_STDIN=1</code></pre>



<p>ตัวอย่าง</p>



<pre class="wp-block-code"><code>echo '{"resource":"/{proxy+}","path":"/","httpMethod":"GET","headers":null,"queryStringParameters":null,"pathParameters":{"id":"1"},"stageVariables":null,"requestContext":{"accountId":"AAAAAAAAAAAA","resourceId":"5agfss","stage":"test-invoke-stage","requestId":"test-invoke-request","identity":{"cognitoIdentityPoolId":null,"accountId":"AAAAAAAAAAAA","cognitoIdentityId":null,"caller":"BBBBBBBBBBBB","apiKey":"test-invoke-api-key","sourceIp":"test-invoke-source-ip","cognitoAuthenticationType":null,"cognitoAuthenticationProvider":null,"userArn":"arn:aws:iam::AAAAAAAAAAAA:root","userAgent":"Apache-HttpClient/4.5.x (Java/1.8.0_102)","user":"AAAAAAAAAAAA"},"resourcePath":"/{proxy+}","httpMethod":"GET","apiId":"t2yh6sjnmk"},"body":null}' | docker run --rm -v "$PWD":/var/task -i -e DOCKER_LAMBDA_USE_STDIN=1 --network mysql -e TEST_LAMBDA_DBCONNECTION="server=mysql;userid=root;password=1234;database=test_lambda;convert zero datetime=True; CharSet=utf8" -e AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128 lambci/lambda:dotnetcore2.1 get_profile::get_profile.Function::Get</code></pre>



<h4 class="wp-block-heading" id="mce_97">ตัวอย่างสาม สามารถใส่ event ด้านหน้า ในรูปแบบ stdin ได้ โดยเรียกใช้ข้อมูลจากไฟล์</h4>



<p>แบบนี้เหมือนกับด้านบน เพียงแต่ผมแปลงนิดหน่อย ให้พ่นข้อมูลจากไฟล์แทน โดยใช้คำสั่ง cat เช่น</p>



<pre class="wp-block-code"><code>cat /Users/chitpong/Sourcecode/aws-serverless/profile/test/get_profile.Tests/SampleRequests/TestGetMethod.json | docker run --rm -v "$PWD":/var/task -i -e DOCKER_LAMBDA_USE_STDIN=1 --network mysql -e TEST_LAMBDA_DBCONNECTION="server=mysql;userid=root;password=1234;database=test_lambda;convert zero datetime=True; CharSet=utf8" -e AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128 lambci/lambda:dotnetcore2.1 get_profile::get_profile.Function::Get</code></pre>



<p>ในที่นี้ผมใช้ JSON ไฟล์เดียวกันกับที่ผมเขียนทดสอบใน Unit Test</p>



<h2 class="wp-block-heading">สรุป</h2>



<p>เป็นรุปแบบการทดสอบ AWS Lambda แบบที่ไม่เสียเงินอีกรูปแบบหนึ่ง และค่อนข้างทำงานได้เหมือนจริงตามที่เราต้องการ ซึ่งถ้าใช้งานบ่อยๆ การทำคำสั่งแบบนี้อาจจะยาวและเสียเวลาหน่อย ก็ให้ไปเขียนเป็น shell script หรือ makefile เพื่อรันก็จะไวขึ้นอีกนิด</p>



<p>ทั้งนี้ทั้งนั้น ผมก็ยังยืนยันแบบเดิมว่า ทดสอบด้วยการเขียน Unit Test เถอะครับ</p>



<p><strong>Reference</strong></p>



<ul class="wp-block-list"><li>https://github.com/lambci/docker-lambda</li><li>https://github.com/lambci/docker-lambda/issues/23</li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/5257/how-to-test-aws-lambda-on-local-machine-via-lambda-docker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ทดสอบ .NET AWS Lambda ด้วย  AWS .NET Mock Lambda Test Tool</title>
		<link>https://myifew.com/5223/test-netcore-aws-lambda-by-aws-net-mock-lambda-test-tool/</link>
					<comments>https://myifew.com/5223/test-netcore-aws-lambda-by-aws-net-mock-lambda-test-tool/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Mon, 18 Feb 2019 13:04:25 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.Net Core]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Serverless]]></category>
		<category><![CDATA[Testing Tools]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=5223</guid>

					<description><![CDATA[ปัญหาหลักของของเขียน Serverless ต่างๆ คือจะทดสอบโค้ดตัวเองอย่างไร ไม่ให้เสียเงินค่า Compute และ Request ตลอดเวลา ยิ่งถ้าโค้ดนั้นไม่มี Unit Test แล้ว ยิ่งยาก เพราะเราไม่สามารถจำลอง Serverless Runtime ได้เอง&#8230;]]></description>
										<content:encoded><![CDATA[
<p>ปัญหาหลักของของเขียน Serverless ต่างๆ คือจะทดสอบโค้ดตัวเองอย่างไร ไม่ให้เสียเงินค่า Compute และ Request ตลอดเวลา ยิ่งถ้าโค้ดนั้นไม่มี Unit Test แล้ว ยิ่งยาก เพราะเราไม่สามารถจำลอง Serverless Runtime ได้เอง</p>



<p>ตัว AWS Lambda เอง เลยออกเครื่องมือตัวหนึ่งสำหรับชาว .Net ชื่อว่า AWS .NET Mock Lambda Test Tool เป็นเครื่องมือที่ช่วยให้นักพัฒนาสามารถทดสอบ Business Logic ของโค้ดตัวเองได้ง่ายๆ ไม่โดนคิดเงิน และคล้ายกับที่ทำงานบน AWS ด้วย</p>



<span id="more-5223"></span>



<h2 class="wp-block-heading">วิธีติดตั้ง</h2>



<p>ติดตั้งเครื่องมือด้วยคำสั่งนี้</p>



<pre class="wp-block-code"><code>dotnet tool install -g Amazon.Lambda.TestTool-2.1</code></pre>



<p>เสร็จเรียบร้อยครับ!</p>



<h2 class="wp-block-heading">วิธีการใช้งาน </h2>



<p>ให้เข้าไปที่โฟลเดอร์ของโค้ดเรา และอยู่ใน level เดียวกับที่มีไฟล์ .csproj จากนั้นรันคำสั่ง</p>



<pre class="wp-block-code"><code>dotnet publish</code></pre>



<p>เพื่อให้ build ไฟล์ DLL binary ก่อน จากนั้นรันคำสั่ง</p>



<pre class="wp-block-code"><code>dotnet lambda-test-tool-2.1</code></pre>



<p>เมื่อรันคำสั่งแล้วจะมีหน้าตาประมาณนี้</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="104" src="https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-command-1200x104.png" alt="" class="wp-image-5225" srcset="https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-command-1200x104.png 1200w, https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-command-1024x89.png 1024w, https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-command-768x66.png 768w, https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-command-600x52.png 600w, https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-command.png 2036w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<p> มันจะทำการ Mock Server ให้เรา จากนั้นมันจะเปิด Brower ขึ้นมา ให้เรากรอกข้อมูล Input เพื่อทำการทดสอบ</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="1043" src="https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-dashboard-1200x1043.png" alt="" class="wp-image-5224" srcset="https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-dashboard-1200x1043.png 1200w, https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-dashboard-1024x890.png 1024w, https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-dashboard-768x668.png 768w, https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-dashboard-600x522.png 600w, https://myifew.com/wp-content/uploads/2019/02/aws-dotnet-mock-lambda-test-tool-dashboard.png 1532w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<h2 class="wp-block-heading">สรุป</h2>



<p>ใช้ง่ายไหมครับ ผมลองตัด Internet แล้วทดสอบ ก็ยังใช้ได้อยู่ แปลว่ามันไม่ได้วิ่งไปหา Amazon เพื่อทำให้เราเสียเงินในการทดสอบ, รวมถึงให้เรา Develop ได้ทุกที่แม้ไม่มีเน็ตด้วย</p>



<p>ส่วนใครคิดจะใช้ ขอให้เขาใจด้วยว่ามันมีข้อจำกัดบางอย่างอยู่ในตอนนี้</p>



<ul class="wp-block-list"><li>YAML based CloudFormation templates are not yet supported.</li><li>No mechanism for setting custom Environment variables.</li><li>NuGet packages that use native dependencies are not supported.</li></ul>



<p>ถ้าถามผม อย่างไรเสีย การมี Unit Test ก็ดีกว่านะครับ 😀</p>



<p><strong>Reference</strong></p>



<ul class="wp-block-list"><li>https://github.com/aws/aws-lambda-dotnet/tree/master/Tools/LambdaTestTool</li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/5223/test-netcore-aws-lambda-by-aws-net-mock-lambda-test-tool/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>มาลอง Code Coverage บน  .Net Core 2+ ด้วย coverlet</title>
		<link>https://myifew.com/5145/code-coverage-on-net-core-2-via-coverlet/</link>
					<comments>https://myifew.com/5145/code-coverage-on-net-core-2-via-coverlet/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Thu, 20 Dec 2018 09:09:35 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.Net Core]]></category>
		<category><![CDATA[Automation Testing]]></category>
		<category><![CDATA[Automation Tools]]></category>
		<category><![CDATA[Code Coverage]]></category>
		<category><![CDATA[Code Quality]]></category>
		<category><![CDATA[Testing Tools]]></category>
		<category><![CDATA[Unit Test]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=5145</guid>

					<description><![CDATA[ใครที่เขียนโค้ดด้วย .Net Core 2+ และทำ CI/CD บน Linux ค่อนข้างยุ่งยากหน่อย เพราะหาเครื่องมือสำหรับตรวจสอบ Code Coverage ฟรีๆ ดีๆ ได้น้อยเหลือเกิน ที่ผมเคยใช้ดีๆ ก็มี minicover&#8230;]]></description>
										<content:encoded><![CDATA[
<p>ใครที่เขียนโค้ดด้วย .Net Core 2+ และทำ CI/CD บน Linux ค่อนข้างยุ่งยากหน่อย เพราะหาเครื่องมือสำหรับตรวจสอบ Code Coverage ฟรีๆ ดีๆ ได้น้อยเหลือเกิน ที่ผมเคยใช้ดีๆ ก็มี <a rel="noreferrer noopener" aria-label="minicover (opens in a new tab)" href="https://github.com/lucaslorentz/minicover" target="_blank">minicover</a> จนเพิ่งมาลองเล่นอีกตัว ชื่อ <a rel="noreferrer noopener" aria-label="coverlet (opens in a new tab)" href="https://github.com/tonerdo/coverlet" target="_blank">coverlet</a> ใช้งานได้ง่ายกว่าเยอะมาก เพราะมันทำงานร่วมกับ MSTest ได้เลย</p>



<span id="more-5145"></span>



<h2 class="wp-block-heading">วิธีติดตั้ง</h2>



<p>การใช้งานมี 2 แบบครับ คือใช้คำสั่ง coverlet ทำงานเลย ให้ติดตั้งด้วยคำสั่ง</p>



<pre class="wp-block-preformatted">dotnet tool install --global coverlet.console</pre>



<p>หรือทำงานผ่านคำสั่ง dotnet test ให้เพิ่ม nuget package ด้วยคำสั่ง</p>



<pre class="wp-block-preformatted">dotnet add package coverlet.msbuild</pre>



<h2 class="wp-block-heading">วิธีใช้งาน</h2>



<p>ในตัวอย่างนี้ โครงสร้างโปรเจ็คผมจะหน้าตาตามรูปภาพด้านล่าง และผมเข้าจะยกตัวอย่างคำสั่งทั้งหมดกรณีที่อยู่ในโฟลเดอร์ /tests/web.UnitTest/<br></p>



<figure class="wp-block-image is-resized"><img loading="lazy" decoding="async" src="https://myifew.com/wp-content/uploads/2018/12/netcore2-project-structure-453x1024.png" alt="" class="wp-image-5146" width="227" height="512"/></figure>



<p>ดังนั้น เมื่อต้องการดู Code Coverage ผ่านคำสั่ง coverlet</p>



<pre class="wp-block-verse">coverlet <strong>bin/Debug/netcoreapp2.1/api.dll</strong> --target "dotnet" --targetargs "<strong>test web.UnitTest.csproj --no-build</strong>" --output "<strong>../web.UnitTest.Results/Coverage.xml</strong>"&nbsp;--format <strong>opencover</strong></pre>



<p>ซึ่งตัวหนาคือข้อมูลของโปรเจ็คเราเอง โดยผู้อ่านสามารถแก้ไขตามที่จะนำไปใช้งานได้เลย</p>



<ul class="wp-block-list"><li><strong>bin/Debug/netcoreapp2.1/api.dll</strong> : คือ ที่อยู่ของไฟล์ Unit Test Binary ที่เรา Build มาแล้ว</li><li><strong>test web.UnitTest.csproj &#8211;no-build</strong> : คือ arguments เพื่อบอกว่าเราต้องการทดสอบด้วย MSTest ไปที่ File Project ไหน, และผมเพิ่มไปว่า ไม่ต้อง ทำการ build project ใหม่ เพราะผมสั่ง build ไปแล้ว (ถ้าใครไม่สั่ง build ก่อน ให้เอา &#8211;no-build ออกด้วยนะ)</li><li><strong>../web.UnitTest.Results/Coverage.xml</strong> : คือ ที่อยู่ของไฟล์ report ซึ่งผมให้ใช้เป็น Formet ของ OpenCover จึงจ้องมีนามสกุล .xml (ค่ามาตรฐาน ถ้าไม่ระบุ มันจะเป็น JSON)</li><li></li><li><strong>opencover</strong> : คือ Format ของไฟล์ report ที่เราจะนำไปใช้งานต่อ</li></ul>



<p>ลองมาดูการใช้งานผ่านคำสั่ง dotnet test แบบปกติบ้าง</p>



<pre class="wp-block-preformatted">dotnet test --no-restore --no-build --logger:"trx;LogFileName=Results.trx" --results-directory:"../web.UnitTest.Results" <strong>/p:CollectCoverage=true</strong> /p:CoverletOutput="<strong>../web.UnitTest.Results/Coverage.xml</strong>" /p:CoverletOutputFormat=<strong>opencover</strong></pre>



<p>ถ้าให้เดาค่าต่างๆ คงพอเดากันได้นะครับ ระบุเหมือนด้านบนเลย แต่คำสั่งหนึ่งที่ต้องมีเสมอคือ</p>



<pre class="wp-block-preformatted">/p:CollectCoverage=true </pre>



<p>เพื่อบ่งบอกว่า เราต้องการ Generate Code Coverage ออกมาด้วย</p>



<h2 class="wp-block-heading">การแสดงผล</h2>



<p>เมื่อรันคำสั่งตามด้านบนเรียบร้อยแล้ว จะได้หน้าตาประมาณนี้ครับ</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="540" src="https://myifew.com/wp-content/uploads/2018/12/Screen-Shot-2561-12-20-at-13.50.06-1200x540.png" alt="" class="wp-image-5147" srcset="https://myifew.com/wp-content/uploads/2018/12/Screen-Shot-2561-12-20-at-13.50.06-1200x540.png 1200w, https://myifew.com/wp-content/uploads/2018/12/Screen-Shot-2561-12-20-at-13.50.06-1024x461.png 1024w, https://myifew.com/wp-content/uploads/2018/12/Screen-Shot-2561-12-20-at-13.50.06-768x346.png 768w, https://myifew.com/wp-content/uploads/2018/12/Screen-Shot-2561-12-20-at-13.50.06-600x270.png 600w, https://myifew.com/wp-content/uploads/2018/12/Screen-Shot-2561-12-20-at-13.50.06.png 1990w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<p>ความหมายที่ได้จากการแสดงผล คือ</p>



<ul class="wp-block-list"><li><strong>Module</strong> : ชื่อ System ที่มันทำการทดสอบ</li><li><strong>Method coverage</strong> : จำนวนของ Function/Method ที่ถูกเรียกใช้งาน</li><li><strong>Branch coverage</strong> : จำนวนของ Branch หรือเงื่อนไขใน if statement ถูกเรียกใช้งานทั้ง true และ false</li><li><strong>Line coverage</strong> : จำนวนของบรรทัดที่ถูกเรียกใช้งาน</li></ul>



<pre class="wp-block-preformatted"><em>อ้างอิงคำอธิบายจาก <a href="http://www.somkiat.cc/introduction-to-code-coverage/">http://www.somkiat.cc/introduction-to-code-coverage/</a></em></pre>



<h2 class="wp-block-heading">กำหนดคุณภาพ ด้วยการตั้ง Threshold</h2>



<p>คราวนี้ ถ้าเราอยากตั้งค่าว่า ถ้า Code Coverage เรามี Test ครอบคลุมต่ำกว่า xx% เราจะไม่ให้ผ่านการทดสอบ โดยเพิ่ม Argument ชื่อ threshold ลงไป ดังนี้ </p>



<p>ตัวอย่างด้วยคำสั่ง coverlet</p>



<pre class="wp-block-preformatted">coverlet bin/Debug/netcoreapp2.1/api.dll --target "dotnet" --targetargs "test web.UnitTest.csproj --no-build" --output "../web.UnitTest.Results/Coverage.json" <strong>--threshold 80</strong></pre>



<p>ตัวอย่างด้วยคำสั่ง dotnet test</p>



<pre class="wp-block-preformatted">dotnet test --no-restore --no-build --logger:"trx;LogFileName=Results.trx" --results-directory:"../web.UnitTest.Results" /p:CollectCoverage=true /p:CoverletOutput="../web.UnitTest.Results/Coverage.xml" /p:CoverletOutputFormat=opencover <strong>/p:Threshold=80 /</strong></pre>



<p>ซึ่งในตัวอย่างผมกำหนดว่า Coverage ทุกประเภทจะต้องเกิน 80% ถึงจะเรียกว่าผ่าน ถ้าต่ำกว่านั้นจะ Fail ทันที ดังรูปด้านล่าง</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="594" src="https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-1-1200x594.png" alt="" class="wp-image-5149" srcset="https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-1-1200x594.png 1200w, https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-1-1024x507.png 1024w, https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-1-768x380.png 768w, https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-1-600x297.png 600w, https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-1.png 2134w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<p>และเราสามารถกำหนดเฉพาะ Coverage ได้ด้วย เช่นผมต้องการเช็คเฉพาะ Line Coverage ก็สามารถเพิ่ม Argument เข้าไป ดังนี้</p>



<p>ตัวอย่างด้วยคำสั่ง coverlet</p>



<pre class="wp-block-preformatted"><strong>--threshold-type line</strong></pre>



<p>ตัวอย่างด้วยคำสั่ง dotnet test</p>



<pre class="wp-block-preformatted"> <strong>/p:ThresholdType=line</strong></pre>



<p>ผลที่ได้คือ</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1200" height="509" src="https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-by-type-1200x509.png" alt="" class="wp-image-5150" srcset="https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-by-type-1200x509.png 1200w, https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-by-type-1024x434.png 1024w, https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-by-type-768x326.png 768w, https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-by-type-600x254.png 600w, https://myifew.com/wp-content/uploads/2018/12/coverlet-under-threshold-standard-by-type.png 2142w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<h2 class="wp-block-heading">สรุป</h2>



<p>ถ้าเทียบกับ minicover แล้ว ตัวนี้ค่อนข้างใช้งานง่าย ไม่ซับซ้อนมากนัก รองรับ .Net Core 2.2.1 ตัวล่าสุดด้วย และสามารถแจกแจงรายละเอียด ตาม Coverage Type ต่างๆ พร้อมออก Report ได้ เช่น json, lcov, opencover (xml file), cobertura (xml file) และ teamcity ถ้าสนในรายละเอียดมากกว่านี้ ไปดูได้ที่ Github ของผู้พัฒนาได้เลยครับ ที่ https://github.com/tonerdo/coverlet</p>



<p><em>Featured image from: https://www.aapnainfotech.com/test-coverage-much-testing-enough</em>/</p>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/5145/code-coverage-on-net-core-2-via-coverlet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>สร้าง API Document กับ .NET Core ง่ายๆ ด้วย  Swagger</title>
		<link>https://myifew.com/4376/generate-api-document-dotnet-core-with-swagger/</link>
					<comments>https://myifew.com/4376/generate-api-document-dotnet-core-with-swagger/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Tue, 06 Feb 2018 17:06:14 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[API Document]]></category>
		<category><![CDATA[Swagger]]></category>
		<category><![CDATA[Testing Tools]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=4376</guid>

					<description><![CDATA[เมื่อโปรแกรเมอร์เขียน API เสร็จ และส่งให้ทีมอื่นๆไปใช้งานต่อ จะต้องอธิบายวิธีการใช้งานด้วย แต่ที่ต้องทำ คือควรมีเอกสารการใช้งาน หรือเรียกว่า API Document ส่งให้กับผู้ใช้เสมอๆ หรือเก็บไว้อ้างอิงที่ใดที่หนึ่ง

แต่กระนั้น โปรแกรมเมอร์อย่างเรามักไม่ชอบทำ API Document หรอกครับ เขียนๆไปแค่ให้มี สิ่งที่ได้มักเป็นเอกสารที่ใช้งานได้บ้างไม่ได้บ้าง เพราะเป็นภาษาที่คนเขียนเข้าใจแค่ตัวเอง หรือตัวอย่างไม่ชัดเจน หรือมีข้อมูลใช้งานไม่ครบถ้วน หนักไปกว่านั้นคือ บ่นว่าไม่มีเวลา แล้วก็ไม่ทำมันซะเลย (แต่มีเวลาไปอธิบายให้ผู้ใช้ทีละคนๆ 555)

ดังนั้น จะดีกว่าไหม ถ้าเราเขียนโค้ด API เสร็จ แล้วมีเครื่องมือสร้าง API Document ให้เราได้เลยอัตโนมัติ, อ่ะ ตอบแทนละกัน "ดีว่ะ!"]]></description>
										<content:encoded><![CDATA[<p>เมื่อโปรแกรเมอร์เขียน API เสร็จ และส่งให้ทีมอื่นๆไปใช้งานต่อ จะต้องอธิบายวิธีการใช้งานด้วย แต่ที่ต้องทำ คือควรมีเอกสารการใช้งาน หรือเรียกว่า API Document ส่งให้กับผู้ใช้เสมอๆ หรือเก็บไว้อ้างอิงที่ใดที่หนึ่ง</p>
<p>แต่กระนั้น โปรแกรมเมอร์อย่างเรามักไม่ชอบทำ API Document หรอกครับ เขียนๆไปแค่ให้มี สิ่งที่ได้มักเป็นเอกสารที่ใช้งานได้บ้างไม่ได้บ้าง เพราะเป็นภาษาที่คนเขียนเข้าใจแค่ตัวเอง หรือตัวอย่างไม่ชัดเจน หรือมีข้อมูลใช้งานไม่ครบถ้วน หนักไปกว่านั้นคือ บ่นว่าไม่มีเวลา แล้วก็ไม่ทำมันซะเลย (แต่มีเวลาไปอธิบายให้ผู้ใช้ทีละคนๆ 555)</p>
<p>ดังนั้น จะดีกว่าไหม ถ้าเราเขียนโค้ด API เสร็จ แล้วมีเครื่องมือสร้าง API Document ให้เราได้เลยอัตโนมัติ, อ่ะ ตอบแทนละกัน &#8220;ดีว่ะ!&#8221;<span id="more-4376"></span></p>
<p>เครื่องมือหนึ่งที่ผมจะแนะนำในบล็อกนี้ ชื่อว่า Swagger ซึ่งมันสามารถสร้างเอกสารการใช้งาน API (API Document) และเครื่องมือทดสอบให้เราได้ในทันที (Testing Tools) โดยมันจะแปลงจากคำสั่งในโค้ดของเราออกมาให้นั่นเอง</p>
<p>ในบล็อกนี้ผมลองใช้ Swagger กับ .NET Core 2 นะครับ สำหรับภาษาอื่นๆ สามารถหาข้อมูลเพิ่มเติมได้ที่ <a href="https://swagger.io/open-source-integrations/" target="_blank" rel="noopener">Swagger Open Source Integrations</a></p>
<p>ว่าแล้ว เรามาเริ่มทำตามขั้นตอนกันเลย</p>
<h2>ติดตั้ง NuGet packages</h2>
<p>ให้เราเข้าไปที่โฟลเดอร์ของ API เราก่อน และพิมพ์คำสั่ง add package ดังนี้</p>
<p>[code lang=&#8221;shell&#8221;]dotnet add api.csproj package Swashbuckle.AspNetCore[/code]</p>
<h2>ติดตั้ง Configure Swagger ใน Middleware</h2>
<p>เพิ่มโค้ดเข้าไปใน ConfigureServices() ของไฟล์ Startup.cs ดังนี้</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
            services.AddSwaggerGen(c =&gt;<br />
            {<br />
                c.SwaggerDoc(&quot;v1&quot;, new Info { Title = &quot;My API&quot;, Version = &quot;v1&quot; });</p>
<p>                var basePath = AppContext.BaseDirectory;<br />
                var xmlPath = Path.Combine(basePath, &quot;MyApi.xml&quot;);<br />
                c.IncludeXmlComments(xmlPath);<br />
            });<br />
[/code]</p>
<p>จากนั้นให้ใส่ using package ไว้ด้วย (โดยปกติ Editor จะเตือนให้เพิ่มด้วย) ดังนี้</p>
<p>[code lang=&#8221;csharp&#8221;]using Swashbuckle.AspNetCore.Swagger;[/code]</p>
<p>จะได้ดังภาพนี้</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4397" src="https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configurationservice-1200x539.png" alt="" width="1024" height="460" srcset="https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configurationservice-1200x539.png 1200w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configurationservice-600x269.png 600w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configurationservice-1024x460.png 1024w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configurationservice-768x345.png 768w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configurationservice-700x314.png 700w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configurationservice.png 1822w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>ซึ่ง Title คือชื่อของหน้าเอกสาร ในที่นี้ผมใช้ชื่อ &#8220;My API&#8221; ส่วนกลุ่มบรรทัดล่างเป็นการขอเปิดใช้งาน Customize ข้อความในรูปแบบของเราเอง ด้วยการระบุข้อมูลเป็น Comment ลงไปในโค้ด (และ Swagger จะทำการเก็บข้อความเหล่านั้นตามไฟล์ XML ที่เราระบุไว้)</p>
<p>จากนั้น เพิ่มโค้ดเข้าไปใน Configure() ของไฟล์ Startup.cs ดังนี้</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
            app.UseSwagger();<br />
            app.UseSwaggerUI(c =&gt;<br />
            {<br />
                c.SwaggerEndpoint(&quot;/swagger/v1/swagger.json&quot;, &quot;My API V1&quot;);<br />
            });<br />
[/code]</p>
<p>จะได้ดังภาพนี้</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4396" src="https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configuration-1200x590.png" alt="" width="1024" height="503" srcset="https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configuration-1200x590.png 1200w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configuration-600x295.png 600w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configuration-1024x504.png 1024w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configuration-768x378.png 768w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configuration-700x344.png 700w, https://myifew.com/wp-content/uploads/2018/02/add-swagger-to-configuration.png 1638w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>เป็นอันเสร็จ ให้ทำการ build และ run ใหม่อีกครั้ง เพื่อลองใช้งาน</p>
<h2>ทดลองใช้งาน Swagger</h2>
<p>ให้เราเปิด browser เข้าไปที่ (แก้ url/port ตามที่คุณตั้งไว้ด้วยนะ)</p>
<blockquote><p>http://&lt;localhost:port&gt;/swagger/v1/swagger.json</p></blockquote>
<p>จะเจอข้อความ JSON ที่เป็นชุดคำสั่งของ Swagger</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4399" src="https://myifew.com/wp-content/uploads/2018/02/swagger-json-raw-1200x442.png" alt="" width="1024" height="377" srcset="https://myifew.com/wp-content/uploads/2018/02/swagger-json-raw-1200x442.png 1200w, https://myifew.com/wp-content/uploads/2018/02/swagger-json-raw-600x221.png 600w, https://myifew.com/wp-content/uploads/2018/02/swagger-json-raw-1024x377.png 1024w, https://myifew.com/wp-content/uploads/2018/02/swagger-json-raw-768x283.png 768w, https://myifew.com/wp-content/uploads/2018/02/swagger-json-raw-700x258.png 700w, https://myifew.com/wp-content/uploads/2018/02/swagger-json-raw.png 2870w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>แต่ถ้าต้องการดูสวยงามด้วย Swagger UI ให้เข้าไปที่</p>
<blockquote><p>http://&lt;localhost:port&gt;/swagger/</p></blockquote>
<p>จะได้หน้าตาสวยงามแบบนี้ครับ</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4403" src="https://myifew.com/wp-content/uploads/2018/02/swagger-ui-1200x715.png" alt="" width="1024" height="610" srcset="https://myifew.com/wp-content/uploads/2018/02/swagger-ui-1200x715.png 1200w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-600x358.png 600w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-1024x611.png 1024w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-768x458.png 768w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-700x417.png 700w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui.png 2858w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>มันจะแสดงรายการ API ของเราออกมาทั้งหมด ตาม Controller/Method/Route ที่เราได้เขียนไปในโค้ดเลยครับ<br />
และเมื่อเรากดเข้าไปดูในรายละเอียดของแต่ละ API มันก็จะแสดงวิธีการ Access, Data Type, Respond Status, Respond Data, Respond Type ครบถ้วน ดังรูป</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4400" src="https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-1200x681.png" alt="" width="1024" height="581" srcset="https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-1200x681.png 1200w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-600x341.png 600w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-1024x581.png 1024w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-768x436.png 768w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-700x397.png 700w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get.png 2872w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>หรืออีกตัวอย่างหนึ่ง ผมลองดึงข้อมูลสมาชิกหมายเลข 2 ออกมา ซึ่งในโค้ดผมบอกว่าต้องระบุ Parameter ให้ด้วย ดังนั้น ตัว Swagger มันก็ได้สร้าง Input ให้ผมได้กรอก Parameter นั้นให้อัตโนมัติเลย</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4401" src="https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-with-parameter-1200x685.png" alt="" width="1024" height="585" srcset="https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-with-parameter-1200x685.png 1200w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-with-parameter-600x342.png 600w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-with-parameter-1024x584.png 1024w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-with-parameter-768x438.png 768w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-with-parameter-700x399.png 700w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-get-with-parameter.png 2860w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>คราวนี้ลองมาดูการส่งข้อมูลแบบ HTTP Post บ้าง ซึ่งมันจะไปดึง Data Structure ของ Model ออกมาให้เราเป็นตัวอย่าง (ตามรูปด้านล่าง กล่องสีเหลืองด้านซ้าย) เมื่อกดที่ตัวอย่าง มันจะมากรอกให้ในช่อง Input ซ้ายมือ เราก็ทำการแก้ไขข้อมูลที่ต้องการใช้งาน ซึ่งในที่นี้ผมทดสอบการเพิ่มข้อมูลสมาชิก เมื่อกรอกเสร็จและกดปุ่ม &#8220;Tyr it out!&#8221; มันก็จะแสดงผลการทำงานออกมาให้เราดังรูปด้านล่าง</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4402" src="https://myifew.com/wp-content/uploads/2018/02/swagger-test-post-data-892x1200.png" alt="" width="892" height="1200" srcset="https://myifew.com/wp-content/uploads/2018/02/swagger-test-post-data-892x1200.png 892w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-post-data-600x807.png 600w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-post-data-761x1024.png 761w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-post-data-768x1033.png 768w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-post-data-520x700.png 520w, https://myifew.com/wp-content/uploads/2018/02/swagger-test-post-data.png 2038w" sizes="auto, (max-width: 892px) 100vw, 892px" /></p>
<h2>การ Customize Document</h2>
<p>ถ้าสังเกตดีๆ มี API ตัวหนึ่งที่มีข้อความโผล่มา ว่า &#8220;Get Member information from id&#8221; ซึ่งอันนี้ผมทำการ Customize เขียนเพิ่มคำอธิบายเข้าไป</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4406" src="https://myifew.com/wp-content/uploads/2018/02/swagger-ui-summary-1200x191.png" alt="" width="1024" height="163" srcset="https://myifew.com/wp-content/uploads/2018/02/swagger-ui-summary-1200x191.png 1200w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-summary-600x96.png 600w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-summary-1024x163.png 1024w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-summary-768x122.png 768w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-summary-700x111.png 700w, https://myifew.com/wp-content/uploads/2018/02/swagger-ui-summary.png 2028w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>ซึ่งในโค้ด API ที่เราต้องการอธิบายเพิ่มเติม ใส่แค่ /// (triple slash) และระบุ  tag &lt;summary&gt; พร้อมข้อความอธิบายสั้นๆว่า API นี้ทำอะไร (ตามภาพ) เท่านั้นเอง, ถ้าอยากยกตัวอย่างหรืออธิบายเพิ่ม สามารถใส่ &lt;remarks&gt; ได้ และยังมี tag อื่นๆ ที่คุณสามารถไปดูได้ที่ <a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=netcore-cli#customize--extend" target="_blank" rel="noopener">Customize &amp; extend</a></p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-4405" src="https://myifew.com/wp-content/uploads/2018/02/swagger-comment-1200x364.png" alt="" width="1024" height="311" srcset="https://myifew.com/wp-content/uploads/2018/02/swagger-comment-1200x364.png 1200w, https://myifew.com/wp-content/uploads/2018/02/swagger-comment-600x182.png 600w, https://myifew.com/wp-content/uploads/2018/02/swagger-comment-1024x310.png 1024w, https://myifew.com/wp-content/uploads/2018/02/swagger-comment-768x233.png 768w, https://myifew.com/wp-content/uploads/2018/02/swagger-comment-700x212.png 700w, https://myifew.com/wp-content/uploads/2018/02/swagger-comment.png 1624w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<h2>สรุป</h2>
<p>Swagger เป็นเครื่องมืออำนวยความสะดวกในการสร้าง API Document เพื่อลดเวลาการเขียนเอง แต่ทั้งนี้ มีเรื่องของ Security ที่ต้องป้องกันไม่ให้คนอื่นเข้ามาได้ หรือให้ดูได้เฉพาะ Development Environment เท่านั้น รวมถึง ถ้าจะให้ Document สมบูรณ์ เราก็ควรต้องเขียนโค้ดให้ถูกต้องโดยเฉพาะเรื่องของการตั้งชื่อตัวแปร ชื่อฟังก์ชั่น โมเดล ฯลฯ เพราะข้อมูลใน Document จะอ่านง่ายแค่ไหน มันสะท้อนจากโค้ดของเรานั่นเอง</p>
<p>&nbsp;</p>
<p>—</p>
<p>Reference: <a href="“https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger”" target="“_blank”">Microsoft.com</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/4376/generate-api-document-dotnet-core-with-swagger/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
