---
title: "Test Demo"
url: "https://courses.osherove.com/courses/tdd-in-net-in-hebrew/test-demo.md"
canonical: "https://courses.osherove.com/courses/tdd-in-net-in-hebrew/test-demo/"
tags: []
author: "Roy Osherove"
description: "Lesson 3 of 22 in TDD in .NET in Hebrew (Day1 - Unit Testing and TDD 101), 34:54. Free video by Roy Osherove."
usage: "Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page)."
license: "https://creativecommons.org/licenses/by/4.0/"
---

# Test Demo

1. [Courses](https://courses.osherove.com/#courses)
2. [TDD in .NET in Hebrew](https://courses.osherove.com/courses/tdd-in-net-in-hebrew/)
3. Day1 - Unit Testing and TDD 101

Lesson 3 of 22

Duration: 34:54 [Watch on YouTube](https://www.youtube.com/watch?v=80H_AvRX6oM) Spoken in Hebrew

## In this lesson

Roy Osherove shows where NuGet comes from and writes the first calculator test with ReSharper, explaining why he picks plain inputs such as 1 and 2 over numbers like 1337 that make a reader wonder. He prefers the TestDriven.NET runner, maps a keyboard shortcut to rerun the last test action, and runs any method under the debugger without a test. He adds a test for negative numbers, keeps random values and logic out of [unit tests](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_17 "Defining unit testing, step by step (The Art of Unit Testing, 3rd ed., ch. 1)"), and replaces the [SetUp method](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-8#sigil_toc_id_162 "Avoid setup methods (The Art of Unit Testing, 3rd ed., ch. 8)") with a [factory method](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-2 "Trying the factory method route (The Art of Unit Testing, 3rd ed., ch. 2)") so each test stays readable on its own.

## Transcript

4,949 words

[\[00:07\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=7s) איך משיגים את הנוגט? הולכים ל tools extension manager הולכים לאנליין gallery זה אוטומטית הולך לה והראשון זה יהיה נוגט מתקינים אותו עושים restart Visual Studio וזהו יש את זה אוקיי עכשיו הוא בא הרעיון בא בכלל מעולם בעולם openסופי ובפייתון יש את הנושא של ג'מס שאתה מתקין דברים אתה עושה בעצם לאיזשהו ג'ם קיבלת רפרס ולפני בערך שנה וחצי הפרויקט הזה התחיל גם בעולם הטנט

[\[00:41\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=41s) בעצם היו שני פרויקטים או שלושה אפילו אחד נקרא open map ואז מייקרוסופט החליטה CPA מאמץ את אחד מהם לחיקה והתחילה ככה לפתח את זה אבל הפרוד הזה היום הוא open source הוא hosted לדעתי ב ב-CodePlex למרות שיש הרבה לחץ להביר אותו לגיטה והיום אם אתם רוצים אתם מגלים היום בג בנוגט אתם אתם אשכרה יכולים לבוא ולהרגיש פץ ולנסות לתקן אותו להוסיף שפ זה די מדהיק

[\[01:12\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=72s) אני אוריד פשוט את הרנס לin שיש לי בפרק כי אין צורך ואת הpages config הpages config זה בעצם מה שבסution explorer הדבר הזה שאומר איזה גרסה של הדpencies יש לך עכשיו מה שיפה זה שנוגט אני יכול גם להריץ אותו ברמת הבילד server שלי ולהגיד לו תביא את הpפendנenes אוטומט ואז אם הם לא פקס קנטרול ואז הוא יביא אותם לפי הגרסה שיש בקונפליק שזה די נחמד אבל זה לוקח קצת זמן אני אישית עדיין בעולם של

[\[01:45\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=105s) לשים את את הפנenנס שלי באיזשהו binary dirקטורy ולשים אותה בחלק מהסורקול זה משתנים לפי הסורקנטרול וגם בזה זה תומך אפשר לשים את כל הבינary בעצם יש ספריה של הבינaries לוקלית בפרויקט שלכם שנוגט יוצר אתם פשוט מוסיפים אותורס אז זה היה בעצם בפוס הזה סיימתי להתקין את [NUnit](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-2#ch02lev1sec3 "First steps with NUnit (The Art of Unit Testing, 2nd ed., ch. 2)") שזה בסך הכל nunit.framework.dll

[\[02:18\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=138s) זה זה אמור להיות כל כך פשוט אני שמח שסוף סוף זה כזה פשוט אז אני אתחיל בלהוסיף testure אביו אז אני מתחיל פה במילה test אבל אין לי פה את הusing אז אני יכול להשתמש במה שקרה smart comptionarter שזה contrול ‏altספס וזה מביא לי את כל הדברים גם אם אין לי אליהם זאת אומרת אני עושה פה test fixure וזה מוסיף גם את בשבילי אז אני לא צריך לכתוב את השם המלא יש את זה בזלס אבל צריך לכתוב את השם המלא ולמי יש כוח שתי

[\[02:51\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=171s) הדבר הבא test public void עכשיו מה השם של הטest שלי אז בואו ננסה לכתוב טס לדבר הזה יש למישהו רעיון מה הוא רוצה לבדוק פה? ‏add אוקי posive numers add two positive numbers ומה אתה רוצה שיקרה

[\[03:30\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=210s) >> לא זה לפחות אני אומר שיש הקשרה זה לא רע >> שפט כדי להוסיף את השטויות האלה עכשיו רישרד בהתחלה צועק עלינו על הדבר הזה הנימי קונש שלנו הוא לא אוהב את זה אבל כולם יודעים שרש לא מבין שום דבר בחיים שלו אז אני עושה alt ואני אומר לו inspection options for ins consistent naming ואני אומר לו shut up עשה לי hint אוקיי אז arange אני יוצרקulatorulator עכשיו קלator הוא לא קיימ לי עדיין אין לי reference לפרויקט אזרפר אני לא צריך לקמפר רשרפר אומר לי זה לא יתקמפל לך

[\[04:02\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=242s) אבל אם אתם רואים פה את המנורה הזאת כל פעם שיש לי את המנורה הזאת אני יכול לעשות alt enter הוא אומר לי היי אבל יש אחד כזה בפרויקט אחר מסול שאני רוצה להוסיף reference אומר לו כן בטח אין שום בעיה אז הוסיף reference אוקיי קקulator c שווה newקulator עכשיו הוא אומר לי פה הי תהפוך את זה לו אני בדרך כלל לא אוהב להשתמש בו אלא אם כן יש לי ממש אני רואה את הטייפ המלא של משהו אני בדרך כלל אני לא משתמש בבר בטestטים שלי אז זה שרשרפר אומר משהו זה לא בכלל חומר שחייבים לעשות את זה רואה המון אנשים שהולכים לפי רשפר בלי לינ לדוגמה לוקחים את כל הלופים הופכים אותם ללינק

[\[04:43\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=283s) אזלינק זה לא קרי by defaultט לי אישית יש בעיה עם לינק אבל כן זה שאומרים לכם לקפוץ מהגג זה לא אומר שחייבים וכולי c add in in x in y מה לשלוח שני של ארב ש >> בטח שזה לא משנה אז מה נשלח ואחד >> אח אחד ואחד אחד ואחד >> עדיף שניים שונים >> עדיף שני שונים >> עדיף שני שונים אז מה לשלוח >> אח ושתח ושתיים למה שתי שנים? למה שני שנים?

[\[05:13\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=313s) אם הסדר משנה >> אם הסדר משנה הוא צודק. >> אם זה היה x כמו שזה בהתחלה אז שזה לא זהx הזה כן אבל זה לא היה מתפל אם היית עושה בתוך הפונקציה בטעות x ועוד x אם היית עושה בתוך הפונקציה בטעות x ועוד >> כן אם הייתי אם הסדר היה משנה של הפרמטרים אז לחלוטין זה סיבה טובה מאוד לעשות שני מספרים שונים אבל למה לא נגיד 42? קודם כל זה מספר שכל הגיקים מכירים זה לא שזה בעיה נכון למה >> 1337 גם

[\[05:44\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=344s) זורק בתקיעות >> לא ליט בן אדם אבל מה הבעיה עם ה יש בעיה עם זה כאילו למה לא לעשות את זה >> כשקורים את >> קודם כל כמה זה ביחד מישהו יודע מה זאת הבעיה א' אם אתה לא יודע לעשות את זה בראש אז זה כבר לא יהונטסט מבחינתנו אה זה צריך להיות קרי >> אה תסה 1338 יפה ועוד אחד 1 ש7 אני בכלל אומר לאנשים תניח שהבן אדם שהולך לקרוא את הטestטים שלך הוא רוצח סדרתי שיודע איפה אתה גר אל תעצפן

[\[06:18\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=378s) ואז אם הוא קורא את הצד שלך ואומר 1337 למה 1337 מה כל כך מיוחד במספר הזה אני אלך לבית שלו ואשאל אותו זה ככה לא רעיון טוב אז אני אוהב להשתמש במספרים הראשונים שהגיוניים לסצנר הזה אז אם זה posive numers אז השניים הראשונים שאני יכול לחשוב עליהם זה בדרך כלל נתפס המוח שלנו רואה את הפטרן הזה אומר אוקיי הם לא משנים אבל אם הייתי אומר ארבע ושתיים זה פתאום נראה מעניין אני רוצה שזה יראה משעמן אני רוצה שזה יגיד אה אחד ושתיים תראו בלי שזה אוקיי זה ממש ממש חשוב אני לא רוצה שלאנשים יהיו שאלות לגבי הטסים שלי אני רוצה שהם יוכלו לקרוא את זה כמו ספר

[\[07:00\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=420s) אמחינתי גם זה סוג של כמו שיש משתנים בלולאות שיש i וJף אחד לא אכפת שקוראים להם i וj פשוט יודעים שזה משתנה זה לא השם שלו לא משנה אז גם פה אבל לפעמים אני לא יכול להשתמש במספר לפעמים כל מספר נראה מוזר אז אני שם את זה באיזשהו משתנה ונותן לו שם נורמלי טוב עכשיו אני צריך את הרultט של הדבר הזה אז אני אעושה פה אstract variable contr alt v כדי לקבל את התוצאה in result

[\[07:30\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=450s) ואל שתחו את הספסing cont v זה לא בalך אגב ריש are equ הראשון זה הectד למה אני מצפה יפה זה לא פרה עצמה >> שלוש זה והט זה result זהו זה הטest הראשון שלי עכשיו בגלל שיש ליפר אז יש לי פה test run אני בדרך כלל לא משתמש בטest run הזה למרות שאם אני אעשה את זה אני יכול להרי את הטestטים שלי פה יכול לראות פה את הטסטר למה לא להשתמש בו תני אסביר

[\[08:09\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=489s) קודם כל תראו איך זה דבר זה נראה מאוד יפה >> זה של רישרט >> זה של רישרט זה נראה מאוד יפה אבל תשים לב כמה זמן לקח לי להריז טסט אחד מסכן והוא זה והוא זה ואז ה הוא היה צריך למלא את כל האייקונים היפים האלה ואז הוא צריך להראות לי את החלון וכולי אני מעדיף משהו קצת יותר מהירש הטestסטר שלו הוא באמת יותר מהיר מMSסS אבל הוא לא מספיק מהר. כשאנחנו מדברים על [TDD](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_27 "Test-driven development (The Art of Unit Testing, 3rd ed., ch. 1)"), הפידבק שאנחנו רוצים הוא הרבה יותר מהר מזה אפילו. הRT runner שאני אישית משתמש בו הוא TestDriven.NET.

[\[08:41\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=521s) TestDriven.NET זה פלאגין שהוא חינמי בponal edition ועולה כסף בנופal edition אבל יש לו כמה יתרונות על הרנרים האחרים כולל רישה. אבל קודם כל אני אראה לכם איך הוא נראה. זה הסימן הזה פה של הט. אוקיי אם אני מריץ את הדבר הזה עם test driven אז כל האoutput נמצא בקונסול אין לי outputפוט ויזואלי בכלל אולי צריך לקמפל הפארמזה בטח שזה יקח יותר פחות זמן כן בוא נשנה פה משהו נעשה פה רווח

[\[09:21\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=561s) לנו ממש ממש אני אוהב אותם נגיד test אומרים זה ההבדל במהירות זה מאוד מאוד רציני אבל יש עוד כמה שיפורים נחמדים בסדר. א' אם אני עושה קליק אם אני מחוץ לטestט אז מריץ את כל הטestטים לקס. אני עושה קליק אם אני ברמת הפרויקט מריץ את כל הטestטים לפרוינקט או ברמת הסולשן. בדרך כלל מה שאני עושה זה אני מריץ את כל הטestטים ברמת הפרויקט ומאותו רגע אני אנסה לא להשתמש בעכבר יותר כדי להריץ את הטestי. מה שאני אעשה לעשות מעכשיו זה יש אtion מיוחד בטest drקר repיט או run את run last action

[\[09:58\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=598s) וכל פעם שאני אעשה רש ואני אוסיף חדש אז הטest הזה ייקלל אוטומטית כי הלס אקשן היה להריץ את כל מה שיש בפרויקט בקופני >> זה עושה את זה אני הולך לעשות שורדקאט כדי לעשות את הדבר הזה אז זה לא עושה כרגע את זה אוטומטית אבל אין לזה שורטקאטס אז היום ביזל סטודו אני יכול לעשות שורטקאט לכל דבר שאני רוצה אני הולך לtools options keבורד ופה בשורה אתם רואים פה את הרשימה הזאת פה יש לכם את כל האtion בתוךסטודיו אתם יכולים לחפש מה שאתם רוצים ולבדוק מה השורטקאט הקיים שלו או לשנות את השורקאט שלו אני הולך לחפש את reun test

[\[10:38\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=638s) אתם רואים שיש לי רק אחד כזה אני הולך לשים פה איזשהו שורטקאט ke וללחוץ הסינ השורטקאט שאני אוהב זה alt r אבל אתם יכולים לעשות מה שבא לכם ק שמו >> אלט אבל בזל הסטודיו מספיק חכם כדי להגיד לי שזה כבר תפוס על ידי משהו מאוד מאוד חשוב כרגע כבר מלא זמן לא השתמשתי בשורטקאט הזה אז זה בסדר אני אתגבר על זה ואני אעשה אס

[\[11:09\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=669s) אוקיי מעכשיו אני הולכת גם לprודאק אני יכול לשנות אותו ולהגיד נגיד פלוס אחד ואני לא צריך לעשות אפילו save אני עושה alt r זה כבר עושה לי save ‏buildד והכל. אוקיי, אני לא צריך להיות בטestטים בכלל. אני משנה משהו פרדקtion ותוך חצי שניה אני כבר יודע מה קורה. אז הוא אומר לי, תשמע, אני רואה את השם של הטest, אני רואה expectד, אני רואה actם יש לי פה את הדבר הזה, זה גם חשוב באטpט כל פעם שאתם רואים את המספר שורה, זה מספר שורה ומספר קול.

[\[11:43\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=703s) כל פעם שיש לי מספר שורה, אני יכול לעשות דאבל קליק על שורה הזאת. זה לא קשור לtestל זה פשוט feature של visual studioent ואז אתם יש לי פה בדיוק את הדבר הזה פה את זה אוקיי ואני רואה שהסריות שלי נשמת יוצא יופיע אז אבל זה לא מה שאני אוהב עדיין בטסט רנדר זה באמת כל הפיצ'רים האלה אחלה אבל אני עדיין יכול לעשות את זה גם עם עם הרישרפט testסט הנה עוד דבר שאני יכול לעשות עם כל הרנרים אחרים אם אני עדיין לא מבין למה הטסט שלי עכשיו אני איך עושים פה break point

[\[12:18\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=738s) ולהגיד או עם ReSharper אני יכול להגיד debag או עם test driver אני יכול להגיד test with debagger ואז הוא מדבק לי את הtest שלי ישר מתוך studio ואני יכול לעשות step in וכולי וכולי הפיצ'ר הבאמת נחמד זה שעם testing אתה יכול לעשות stepפ in גם בקדפuc גם אם אין לך הטestטים בכלל אני יכול ללכת עכשיו סתם לפונקציה פה להגיד פהפ point או אפילו פה נגיד נניח שאין לי אפילו test אחד בחיים שלי test with debugger

[\[12:56\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=776s) הוא אוטומטית מפעיל את הפונקציה הזאת עם reflectiontion נותן לערכים default values ואני נכנס לעשות steping to theפציה אז אם אני רוצה אני יכול לעשות את productiontion c פונקציה קטנה שקורת לפונקציה אחרת עושה לה set into debug with test with debugger ואני לא צריך לכתוב consolול אפליקש יותר לא צריך לעשות שום דבר אני יכול לדמות איזה ערך שאני רוצה את ערך זה אחד הדברים שחוסכים לי המון המון זמן כשבעיקר בלגסו אז זה באמת אחד הדברים הכי יפים בטסרים האלה שהוא נותן את הפיצ'ר הזה ואף testר אף רנר אחר לא נותן את זה

[\[13:30\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=810s) אוקיי אז אני רק אבוד שהפעולה האחרונה שלי זה run all testing project ומעכשיו alt r פשוט יחזור על הפעולה הזאת שעלה לגבי testing יש לו דרך טיפה יותר נורמלי כ test results >> זאת זאת הדרך הנורמלית הקונסול הזה >> זאת הדרך הנורמלית מבחינתי אם אני אני רואה את זה בקונסול זה כל מה שאני צריך אני צריך לדעת אם משהו נכשל או לא צריך לדעת שהכל עבר 17 אז אני אוכל לראות את הרשימו שלהם בטח יש לו גם >> לא אין לו יש לו בפה של

[\[14:01\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=841s) >> זה הui הזה אני מתכוון הפרס runר שלו יכול לראות שם >> וואלה הוסיף את זה >> אני אני לא מכיר את הפיצר הזה אני רק יודע שאני יכול להרוג אותו אבל וואלה אם יש לו את הפיצ'ר הזה אחלה אבל אני אני ניסיתי עכשיו ולא ראיתי שום דבר אבל אני אומר לכם בתהליך הטd בדרך כלל אתם מתחילים אתם לא מתחילים 17 טס נכשלים אתם באים אתם משנים שורה פתאום 17 נכשלים רגע רגע אנדו אוקיי עכשיו בוא נעשה את זה קצת יותר קטן או עכשיו רק אחד נחשל או אתם מתחילים את זה שנכשל אתם מריצים משנים את הקוד אף אחד לא נכשל זה באנך שלי אבל כרגע אנחנו עדיין לא שם אני רק עדיין ממשיך לקנפג את הסביבה שלי

[\[14:47\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=887s) אני אתקן את הבאג פה alt r מצוין שיפט state לסגור את החלון ועכשיו אני יכול לכתוב טestט חדש אני עדיין לא עושה רפאקטורים אבל יש לי פה רצון מאוד גדול פשוט לשכפל את הטestט הזה זה יש לי קצת בעיה עם זה אני מאוד אני יש לי בעיה עםקופסטינג אבל מה שאני אעשה במקום אני אקנק את הסביבה שלי שזה לא יהיה באסה לכתוב חדש

[\[15:18\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=918s) אז כדי לעשות את זה אני אלך לרישר פירות כבר ואני אכתוב אלך לtמפל explorer ואני אצור לי tempליate חדש ליצירה של test אז יש לי פה את הכפתור הקטן הזה אתם רואים את זה נקרא טמפליט יצירה של טסט מה שקורה זה שפה אני אכתוב איזה איזה מילה איזה coddewור נגיד test וכל פעם שאני אכתוב test יופיע לי test ואז אם לחץ טפט ואז כל הקפוד שיש למטה יכתב אוטומטית יכול קצת יותר חכם test מה זה

[\[15:51\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=951s) תכף נדבר על קונטרול s כדי לשמור את זה כרגע סתם עשיתי פיסט לקוד שלי אוקיי עכשיו אם אני הולך לtest אז אני מקבל את הדבר הזה התחלה טובה כבר ההבדל מסניק זה שאני לא צריך לעשות XML זה כבר ממש ממש ממש וחבר שני שני זה עדיין לא מספיק טוב. מה שאני רוצה זה שהטestט שלי יהיה קצת יותר דינמי. לדוגמה אני אשים פה לא רואים את זה אני שים ככה

[\[16:30\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=990s) אני אשים את זה בין שני דולרים unit of y אוקיי מה שאומר שעכשיו זה יהיה דינמי אם אני אחשוב חשוב test אני מקבל את הדבר הזה טוב כואב ככה עכשיו אני יכול לכתוב טמפליטים הרבה יותר חכמים אז מה שאני אוהב לעשות זה לשים פה unit of workרio ו כל מה שבין שני דולרים נהיה דינמי ויש פה עוד איזשהו קיבוורד אחד נחמד שנקרא

[\[17:00\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1020s) ופה הקרס יסיים את החיים שלו כשאני מסיים את העבודה פה אז אם אני עושה עכשיו test אני יכול לכתוב אוקיי סנר מה היה הסנר שאני רוצה לבדוק עכשיו >> אוקיי נגטיב ‏first מה שמינוס אמור להגיד מה מינוס בעצם אומר תחשבו

[\[17:36\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1056s) כי מחר er value זה יהיה מינוס3 אני אכתוב פה מ1 אז הטest שלנו מאוד cלמation אנחנו צריכים להגיד את זה כדרישה אם אני נותן לו משהו נגטיבי הוא נותן לי איזשהו er number משהו שמסמל אוקיי אז עכשיו אני אעשה newקulator structable c יש לי כבר בעיה עם השי הזה נכון נעשה פה entulator

[\[18:11\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1091s) מה ניתן עכשיו >> מה >> מינו2 מ ש >> מה דחיף >> אה מינוס מינוס לא ב >> ואחד >> מינוס1 ואחד >> מה אתם אומרים זה נראה מעניין מדי >> מינוס ושת >> כן גם >> מה אתם אומרים נראה מעניין מדי >> אה מה עם אפס >> גם מעניין מדי >> כי זה בעיה כי אני כל מקור מקבל מינוס 2 מינו 2 >> 2 ומינוס2

[\[18:45\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1125s) כמה תרוח לאפס נפתור של שני מספרים לא מינוס אם תן אחד מינוס שתיים תמות מינוס איתך חברות החלטו אני בכוחן צודקים אבל יש לי עדיין בעיה הרוצה סדרתי יבוא יגיד מינוס ש ושת פה משהו מיוחד >> מינוס שפ מ2 שפ >> אין פה מספר טוב אין פה מספר טוב אני אגיד מה שאני אוהב לעשות זה ככה זה ונעשה פה ‏variable in su posive

[\[19:16\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1156s) פה מינוס אחד וגומר עניין אוקיי יותר מדי הדיון הזה זה אומר חיל להעביר אומרים אם אם יש ספק אז זה אין ספק גם מינוס אחד פה בלי >> כי זה יחזיר מינוס אחור חזיר מינוס אחד יודים לחשוב שתחס מינוס אחד כי קיבל ששם נגטיב פה זה גם אחת טוב נגטיב זה גם >> השאלה היא כזאת אם אני עושה פה מינוס אחד הטסט שלי אמור להיכשל או לעבוד

[\[19:48\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1188s) אב >> לא עשיתי עדיין את הסרט נכון בוא נצא את הסרט ואז נראה מה מה קורה זה שאנחנו יודעים שזה מינוס אחד עדיין לא חשוב לנו אנחנו צריכים לדעת שהסימבול ומינוס אחד עם אותו דבר אז תכף נראה איך אנחנו פותרים את הדבר הזה הסט עכשיו הנה הI השני שיש את העניות אם אתם לא אוהבים את equal אתם יכולים לעשות assert

[\[20:19\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1219s) In result that result is equ to מינוס 1 בסדר ירוץ לא ירוץ מסע יותר בום עבר אבל פה באמת אם אנחנו יודעים ש אני רואה פה מינוס אד ואני רואה פה מינוס אד עד עכשיו הטסט הזה עוד פעם לא קרי אוקיי ולכן אני יכול להגיד בוא נגיד ככה אם אני יכול להגיד שזה שהultט is equal to אcat

[\[20:56\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1256s) Er איזשהו ‏in static ש אוקיי עכשיו שימו לב תראו גם השורה הזאת יותר ארוכה אני אישית לא אוהב את הביא את זה אני אישית הרבה יותר מעדיף את

[\[21:26\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1286s) As equalator er value כי פה אני רואה מה אמור לקרות רק בסוף השורה ולפעמים השורה יכול להיות מאוד ערוכה ופה אני רואה את זה הרבה יותר טעים וזה באמת החלטה זה כבר עניין של טע אבל גם פה אני מבקש תהיו קונסיסטנטים אם אתם חטים שאתם משתמשים באחד תשתמשו רק באחד מהם פה הקונבנשנ שאתם משתמשים קבוצות מאוד חשוב שלאנשים יהיה קל לקרוא את הטestטים אחד של השני >> מישהו יש בעיה להשתמש בריקול

[\[21:58\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1318s) יופי מעולה >> נבחר אבל >> אני יכול גם להגיד פה מינוס אצה פה מינוס2 אני מור ועכשיו גם פתרתי את הבעיה שאני רואה אני יודע שזה מינוס ואז טכנית יש לי בעיה עם זה וגם פתרתי את בעית הנגטיבי >> אבל לא השתמשת בסך בקוד >> במה לא השתמשת בק >> זה כבר רפקטורינג קודם כל אני גורם לזה לעבוד זוכר

[\[22:28\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1348s) עכשיו אני יכול גם ללכת לקודש ולהגיד אוקיי אני יכול ללכת ולהחליף את זה בארוב כל הטestטים עוברים אז את יכול להחזיר עכשיו שנית עשיתי ריפקטורing אני בודק שלא שברתי שום דבר אל תעה הוא שאני עושה ריפקטורing אחרי שיש לי טestingים לא לפני כי אם אני עושה ריפאקטורing בזמן שהט שלי עוד נכשל אז אני לא יודע אם הוא ממשיך להיכשל לעובר בגלל מה שעשיתי אז הטמפטליט הזה חשוב עוזר מאוד הטest הזה נראה די סביר פשוט בגלל הפרונטים הגדולים זה נראה ארוך מאוד

[\[23:02\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1382s) אמ שאלות הטסט הטestטים שיש לי בינתיים הם בסדר שיש לי משהו שדה לי לעשות >> ואיך תשובה חיובית גם אם לא היה אקספש מינוס שח יוצא גם מינוס ולח בלי שיהיה טאבליק ש >> אוקיי אז אני יכול זה באג לדעתך >> זה אומר שהטסט לא באמת כאילו אני לא יכול לדעת מכאן שבאמת הפונקציונליות הזאת אני יכול לדעת מכאן לא >> מכאן אני יודע שהחיובי עובדת אבל אני לא יודע שיש את הבעיה של הירור רנדלינד למטה כלומר אני לא יודע שבאמת זה עובדים אני >> אוקיי מינוס שלוש >> זה בסדר >> אחלה

[\[23:44\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1424s) >> אבל אם מלכתחילה היית כותב 1337 זה לא היה קורה >> כאילומסמספרים שהם קטנים הם יש יותר סיכוי שבמקרה עלית על איזשהו מספר מיוחד כמו למשל פה מינוס2 ואחד במקרה עליתה על משהו מיוחד אם אם לכתחילה אתה כותב טסטים עם מספרים שהם מופלצים, הם איזה 1000 ומשהו אז אז יש פחות סיכוי שהטestט יעבור בטעות. אוקיי? אפשר יש יש יש איזשהי אמת בזה אבל אני מעדיף לטות לצד של הרדבילי ולגלות אם יש לי בעיה אחר כך במיוחד אם אני אוהב testבן אני אגלה את זה מהר מאוד אבל הרדבילי בלי רדבילי זה לא משנה כמה הטestטים שלי נכונים כי אם אף אחד לא מבין למה הטסט שלי נכשל מחר זה לא משנה כמה הוא נכון לכן הרדבילטי זה אחד הדברים שהכי חשובים לי כרגע

[\[24:31\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1471s) אם אני יכול לקבל רדבילי ונכונות תוך כדי אני מעדיף את זה לכן אני מתחיל מרדבילי ואחרי זה מקסימום אני אשנה את זה לנכונות תשים לבגיד הוא מתא את הבאג הזה אבל אם אם הפיצ'ר הזה עדיין לא קיים אני צריך להתחיל ממש שנכשל ואז לגרום לו לעבוד נכון ואם הייתי ואם הייתי צריך להתחיל ממשהו שנכשל אז הייתי כותב את הקוד בצורה אחרת זאת אומרת הייתי מגלה שיש לי פה איזשהו משהו שאני מצפה לו בכל מקרה או שהייתי כותב טestט אחר שמוכיח שביתן שני ויוז אחרים אני אקבל מינוס אחר אבל בtd הייתי יכול להגיע למצב שבו הטestט הזה משקר לי כי טestט אחר היה מוכיח שיש פה איזשהיא נכונות אחרת נראה לי שזה עניין של קונבנציה אם כולם יודעים שמספר גדול לא יודע אפילו מחליטים ל איזשהו מטווח של מספרים שהם בטestטים לא יודע אם כולם יודעים שזה בסדר לשים מספרים גדולים אז אז זה נראה לי גם נכון יותר וגם זה לא >> כל זמן שזה קרי אין לי שום בעיה אם נגיד יש לך איזה קונסט של מספר גדול שאתה אוהב אז תשתמש בקונספט אין לי שום בעיה כל זמן שאני מבין בטסט מה לז זה למהור לקרות

[\[25:31\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1531s) ולמה זה קורה אם אני רואה מספר גדול אבל אני לא חושב זה בראש זה בעיה אני רוצה שיהיה לי לקרוא את זה ולהגיד שאני יודע מה עומד לקרות. אם אני צריך לשאול אותך מה זה המספר הזה אז כבר יש בעיה כי אני כי הטסט לאט לא מספיק מובד. אוקיי? >> אם מכפילים ב10 למשל זה גם >> מכפילים את מה ב-10? >> את כל המספרים. >> אין לי בעיה להכפיל ב-10. אני גם יכול להיות ככה. מינוס 10 ו-30. >> כן. אפשר לחשב את זה בקלות. זה קר. >> נכון. אבל אבל יש יש אבל זה משהו שחשוב להבין. אם אני יכול להוכיח את זה מספרים יותר קטנים בTD אני מעדיף כי יכול להיות שמספרים גדולים זה עוד פיצ'ר אתה מבין אוקיי >> מכ שמדובר תחשוב על פס של טס ולכן ככל שזה יותר פשוט זה רוב סיפים שזה אינפרנטלי

[\[26:14\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1574s) ומכיוון שהרב פעמים אתה לא יודע לאן תגיע עם הדברים האלה אז אני מעדיף להתחיל מהדברים הפשוטים אם אני מתחילים מהדברים הסמוכים יכול להיות שכבר עשיתי לעצמי יותר מדי עבודה כדי לפתור כן >> איפה תגיד מה לגבי אם הייתי לגבי הקראיות אם הייתי אומר פונקציה get ‏number get posive number מחזירה לי כל פעם מספר חיוקי אחר >> האם היית משתמש באיזשהונדום נבר >> האם כן זה נחשב פרקטיס שהוא ממש לא טוב כי אז אי אפשר לצפות בטסט לעבור או שזה נחשב כי זה יכול לה >> אני יודע שהרבה אנשים משתמשים בזה אני אישית לא אוהב להשתמש בזה מבחינתי זה לא [unit test](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-1#ch01lev1sec1 "Defining unit testing, step by step (The Art of Unit Testing, 2nd ed., ch. 1)") אין לי בעיה להשתמש בזה אבל אני לא שם את זה בפרויקט שנקרא unit test אני שם את זה בפרויקט שנקרא inration test בגלל שאין לי שליטה על הרנד ואם מחר הטest שלי מגלה בג נורא קשה לי לשחזר את הטest אתה אומר שכל כל test וניטest חייב להיות החשיטה עצמה הוא חייב להיות צריך להיות prקctable >> רגע מה זוג יכול להיות האם הוא גדול מאפס

[\[27:08\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1628s) >> אבל אני לא רוצה שיהיה לי לוגיקה בטסט אם יש לי לוגיקה בטסט יכול להיות גם בג בטest כמו nrq is greater than משהו כזה >> יש rד אבל אני רוצה לדעת את המספר הפשוט המטרה שלי עכשיו היא הטest הכי פשוט ואם זה יותר גדול אולי זה לא המספר הנכון זה הדקה שצריך לזוג אם גדול מאפס כמו שפה זה צריך להיות מינוס אם בוא אגיד לך אם אתה תגיד גיע לרנדום בוא נניח שאתה מיצר שני random numers איך אתה איך אתה יודע שהרכיבו אותם בלי בלי לשחזר את הלוגיקה של הפרדקtion בטestטים

[\[27:38\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1658s) אוקיי עכשיו אם אתה משחרר את הלוגה של הפרודקש בטestטים אתה עושה את הפלוסים בעצמך בטסט >> יש לך את הבאג הזה ויש לך באג בפודקצ אתה משחזר אותו גם בטסט שלך עובר אתה לא מגלה את הבג לכן אני תמיד משתמש בדקed values כדי לדעת מה אמור לקרות כי זה הend resultלט שלי אני לא רוצה לדעת איך קיבלתי אותו >> גם יכול להיות שהטest פעם יעבור ופעם לא יעבור אתה עושה alt r זה עובר alt r זה לא עובר זה לא התנהגות ש לא קונסיסטנטי אבל כן רנדום זה בסדר זה פשוט לא אז כדי לדחוף developופment אני לא משתמש ברנ כי אני רוצה משהו קונסיסטנטי שמוכיח לי שמשהו לא בסדר והמשהו הזה אחרי זה תמיד יעבור אחרי זה אני אוסיף את הטestטים עם הרנדם בפרויקט מופד אין לי שום בעיה עם זה אבל אני לא אגיד שזה יוני testing בגלל שאלה באמת טestטים שלפעמים יכולים לעבור ולפעמים לא וכשהם לא אז נורא קשה לשחזר אותם כי אז אני צריך לתחוד לעשות לוגינג מה באמת שלחתי מה יוצרתי כל הטestט יהיה הרבה יותר מסובך אז אז טestטים מסובכים אני לא כותב פה פה זה טestטים שהם קריאים ועוזרים לי לדחוף את הפיצ'רים שלי קדימה אוקיי בגלל זה אני גם לא כותב טestטים עם פרדים כי גם בפרדים אין לי שאני הטסטים

[\[28:38\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1718s) יקחו הרבה יותר זמן טסטים שאני מריץ צריכים להיות מהירים צריכים אני צריך לקבל תשובה כמה שיותר אה עוד שאלות כמובן שמה שאתם רואים עכשיו זה דוגמה לפיצ'ר הכי פשוט שאנחנו פעם יכולים לחשוב עליו אבל צריך לדעת לכתוב טסים גם לפיצ'רים האלה הרבה פעמים הבדנ בלוק של הרדילity ומטביל שם שמשוים גם בטestטים המסובכים אבל הטest הזה הוא עדיין לא maable יש עדיין בעיה פה אני עדיין קורא לקונסטרקטור עכשיו יש כמה featureים ב-NUnit וגם בMS test שעוזרים לנו לפתור את הבעיה של ה של repating yourself יש אבט שנקרא setup

[\[29:14\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1754s) לא עשה culture setup setup זה בעצם אטריבט שאומר למתודה שמתחתיי אוקיי ‏before הקוד הזה יקרא כל פעם right line before אם אני אריץ עכשיו alt r אתם רואים שה הקוד הזה רץ פעם אחת לפני כל test

[\[29:47\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1787s) אני יכול להשתמש בקוד הזה כדי להתחל משתנים ברמת הקלאס ואז אני מגדיר אותם פעם אחת ומתחל אותם באותה צורה לפני כל טestט זאת אומרת אני יכול להגדיר את אקulator C ברמת הקס אבל אני לא רוצה להתחיל אותו ברמת הקלס אני רוצה להתחיל אותו ברמת הסדר שווה יופי שר עדיין לא כזה חכם

[\[30:19\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1819s) ופה אני יכול להגיד C שווה קulator עכשיו אני לא צריך להתחיל את קלקולטור בכל הטestטים פה ופה אשרה את זה לC כל הטסטים עדיין עוברים ועכשיו אם מחר אני משנה את הקונסטרקטור שלי ומסיף לו פרמטר אני לא צריך לשנות עכשיו את כל הטestים אני משנה רק במקום אחד והמטנability שלי עולה

[\[30:49\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1849s) כביכול פה שלב אבל יש פה בעיה יש עדיין משהו שאני לא אוהב בטסטים האלה יש לכם רעיון אם אתם עושים רויwתם מסתכלים על הטestט הזה מה אתם רוצים יש לכם איזשהי מחשבות חיוביות או שטליות >> אה COF is C נכון זאת בדיוק הבעיה שכדי להבין את הטסט הט אני עכשיו צריך להסתכל בשני מקומות כן אני יכול לשים את העכבר שלי פה ולראות שזה קל לי לטוב אבל אני לא יודע מתי הוא נוצר כמה פעמים כבר השתמשו בו האם באמת שמו אותו בסע

[\[31:21\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1881s) אז אני לא רוצה שבן אדם יצרך לקרוא שני דברים כדי להביא את הטסט שלי אני רוצה שהטest שלי יהיה אקספליסיט ומובן לחלוטין ולכן אני ממליץ לא להשתמש בסדר כמעט אף פעם רק בגלל שהפיצר הזה קיים זה לא מה שמונלץ להשתמש בו במקום זה אני אעשה ויד את כל הדבר הזה אופס דבלתי

[\[31:56\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1916s) הנה יפה יש לי פה עוד שני טסטים שלי אוקיי ווריד את כל הספ בסדר הבעיה שלי עכשיו זה עדיין חזרתי לבעיית המטבity נבדוק שהכל עדיין בסדר אבל במקום להשתמש בסטא מה אני יכול לעשות כדי להיות גם readable וגם mainable במקום זה אני מעדיף להשתמש בקטור פשוט לעשות מדקול עד למתודה נקרא להט

[\[32:30\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1950s) בגלל זה גם חשוב לי לעשות את זה כמה שיותר מוקדם אחרי שיש לי שני טסים לא שלושה כדי שהעלות של לשנות את זה אחר כך היא תהיה מאוד נמוכה את זה בזמן שאני עושה את זה עכשיו כל הטסטים שלי עדיין עוברים הטest שלי הוא readable אבל אם מחר אני מוסיף פה דברים לקונסטרקטור אז אני יכול לתת פה defaultט valאפט לי מר כן אכפת לי מה שאני שולח לקונסטרקטור אני יכול לעשות טסטים במיוחד עם הולז האלה ולא להשתמש בפאקטורים האיכות הזה אני גם יכול ליצור פקטור מוד עם קטור יכול לעשות פקטור מוד עם קולטור שכבר קראו לו שלוש פעמים אם אני רואה שאני חוזר על עצמי אבל רק אחרי שאני רואה שאני חוזר על עצמי

[\[33:06\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=1986s) כן את השאלה שמעתי מישהו אומר משהו >> עדיין נקרוא כאילו לראות את הקוד בשני מקומות עדיין ניצח פה להיות ל >> לא אני רואה פה שאתה מייצר לי כל יותר חדש אני לא צריך לקרוא ש אני יודע שהוא חדש אז אני לא צריך ללכת להסתכל אוקיי אם אני באמת ארוצה לדעת איך נראה חדש אז אני יכול להסתכל אבל בדיפa יש לי הרבה יותר מידע אני לא צריך אני כבר יודע שגם יש לי קלקulator אני יודע מה הטy שלו כי זה לא

[\[33:39\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=2019s) וגם אני יודע שהוא חדש כי כתוב make לא כתוב גט אם כתוב גט אני לא יודע אם הוא חדש אוקיי בואו בואו בוא נוסיף עוד פיצ'ר לדבר הזה אני עדיין לא עובד test driven אבל כרגע יש לי פה גם איזשהו פאג נכון נכון? זאת אומרת אני כרגע לא בודק את הפרמטר השני. אז בוא נניח שיש לכם קוד וקלייתם בג כזה. אם אני רוצה לתקן את הבאג, אני לא אני לא אלך ואתקן אותו. אני קודם כל אכתוב לו טestט. קודם כל אני אנסה להכו את הבאג הזה.

[\[34:10\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=2050s) אז עכשיו אני יכול לבוא ולהגיד, אוקיי, יהיה לי בגדול את אותו טestט, אבל אני אשלח פרמטרים שונים, נכון? זאת אומרת בגדול זה נראה כמעט אותו דבר אפילו השם שלו אמור להיות אותו דבר הדבר היחיד שמתחלף זה הערך של זה וערך של זה נכוןס >> וסקנד פרמטר נכון אז אני יכול לעשות את הדבר הזה וזה באמת מהר מאוד אני אגיע למצב שבאמת יש לי שני טestטים שניהם קריאים שני אבל יש דרך יותר פשוטה לעשות את הדברים האלה אם באמת יש לי את אותו טestט

[\[34:50\]](https://www.youtube.com/watch?v=80H_AvRX6oM&t=2090s) אז אני לא חייב לעשות את הדברים בצורה הז

## Related

- [Replacing beforeEach() completely with factory methods](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-2) · The Art of Unit Testing, 3rd ed., ch. 2

    Book section on replacing setup methods completely with factory methods, the same refactoring done to the calculator tests.

- [Magic values and naming variables](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-9#sigil_toc_id_169) · The Art of Unit Testing, 3rd ed., ch. 9

    Covers magic values and naming variables, matching the lesson's choice of plain inputs like 1 and 2 over 1337.

- [Avoiding logic in unit tests](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-7#sigil_toc_id_141) · The Art of Unit Testing, 3rd ed., ch. 7

    Book section on avoiding logic in unit tests, as the lesson advises when keeping random values and logic out.

- [Writing your first test](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-2#ch02lev1sec4) · The Art of Unit Testing, 2nd ed., ch. 2

    Writing a first NUnit test in C#, the same step the lesson takes with the calculator class.

### Also linked in this lesson

#### The Art of Unit Testing, 3rd ed.

- [Defining unit testing, step by step](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_17), ch. 1
- [Avoid setup methods](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-8#sigil_toc_id_162), ch. 8
- [Test-driven development](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_27), ch. 1

#### The Art of Unit Testing, 2nd ed.

- [First steps with NUnit](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-2#ch02lev1sec3), ch. 2
- [Defining unit testing, step by step](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-1#ch01lev1sec1), ch. 1

[Previous lesson Syntax](https://courses.osherove.com/courses/tdd-in-net-in-hebrew/syntax/) [Next lesson Test Cases, String Asserts and more](https://courses.osherove.com/courses/tdd-in-net-in-hebrew/test-cases-string-asserts-and-more/)


---

## About the author

**Roy Osherove**: Senior Solutions Architect at AWS working on AI for production and AI-driven development; author of The Art of Unit Testing and Elastic Leadership, with about 20 years of consulting and training on unit testing, TDD, team leadership and continuous delivery.

### Sites

- [RobotPaper](https://robotpaper.ai/): This blog: AI patterns and anti-patterns, AI and coding agents, and engineering leadership.
- [osherove.com](https://osherove.com): Roy's personal site. Author of The Art of Unit Testing and Elastic Leadership; consulting and training on unit testing, TDD, team leadership and continuous delivery, plus about 20 years of blog posts.
- [The Art of Unit Testing](https://www.artofunittesting.com): The Art of Unit Testing, 3rd Edition (Manning): readable, maintainable, trustworthy unit tests, plus TDD workshops in C#, JavaScript, Java and Kotlin.
- [5whys.com](https://www.5whys.com): Roy's writing on software team leadership: self-organizing teams, surviving chaos, learning mode and the Elastic Leadership model.
- [Pipeline Driven](https://pipelinedriven.org): Continuous delivery and DevOps practices: build patterns, pipeline-friendly testing, DevOps metrics and enterprise DevOps.
- [Elastic Leadership](https://www.elasticleadership.com): Elastic Leadership, Roy's framework for software team leaders (survival, learning and self-organizing modes).

### Social

- X: https://x.com/royosherove
- LinkedIn: https://www.linkedin.com/in/osherove/

### Contact

- Contact form: https://forms.gle/jQSx5KoXvrVA1JCK7

### License

Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page). License: https://creativecommons.org/licenses/by/4.0/
