בדיקות אוטומטיות בדרופל

הצגת מודול בדיקות לדרופל שמאפשר בדיקות אוטומטיות עם Jasmine עבור סביבת דרופל ויכולות DevOps מלאות עם phantomJS ו-drush!

בדיקות אוטומטיות בדרופל זה שמה של ההרצאה שהעברתי ממש עכשיו בדרופל קאמפ 2013. לצערי ההרצאה לא עלתה יפה עקב תקלה טכנית שמנעה ממני לפתוח את קישורי הדוגמה שהכנתי ומנעה מרוב הנוכחים באולם להבין כמה קל זה לעשות בדיקות. תימללתי את ההרצאה ואני מציג אותה כאן כולל הקישורים וההסברים.

למה צריך בדיקות אוטומטיות?

בדרך כלל כשמדברים על בדיקות אוטומטיות, רוב המפתחים עושים פרצוף מוזר. מה לנו ולבדיקות? יש לנו איש QA, במקרה הטוב או הלקוח במקרה הפחות טוב והוא זה אחראי על הבדיקות? איך הוא בודק? באמצעים ידניים בדרך כלל – נכנס, מקליק על כמה דברים ואז מלין על כך ששום דבר לא עובד. רבים איתו קצת, מקללים אותו קצת וממשיכים הלאה.
המתודה הזו, בדיוק כמו אקספלורר 6, היתה טובה ללפני עשר שנים. כיום – גם אם אנו מפתחים סדרתיים של פרויקטים קטנים ובמיוחד אם אנו מפתחים פרויקטים גדולים ונרחבים – אי אפשר להמלט מבדיקות אוטומטיות.

אני לא אכנס כאן לדיון ארוך ומפותל על למה 'צריך' בדיקות אוטומטיות. כולנו כאן מפתחים, כולנו הוזעקנו באמצע הלילה/באמצע דברים אחרים לתקן באג חשוב בפרודקשן וכולנו רוצים למזער את זה.

רוב האנשים נרתעים מבדיקות אוטומטיות כי כביכול צריך להשקיע טונות של זמן ואנרגיה בבנייה ותחזוקת סביבת בדיקות מורכבת. אם מישהו מחפש 'בדיקות אוטומטיות' סביר להניח שהוא ייתקל בכל מיני מונחים כמו jenkins, chef, puppet ואחרי שעתיים הוא יכנס לפינה ויבכה. מטרת ההרצאה שלי היא להראות בגדול את אחד הפתרונות הטובים, הפשוטים והיעילים ביותר לבדיקות אוטומטיות בדרופל ואני אראה לכם את שלבי 'ההתקנה' של סביבת העבודה ובסיום ההרצאה הזו המטרה שלי היא שגם אתם תדעו ליצור בדיקות אוטומטיות בדרופל והכי חשוב – להריץ אותן.

ישנם לא מעט פתרונות בדיקה קיימים, אבל העדפתי להתמקד באחת על מנת שיהיה סיכוי שתצאו מההרצאה הזו עם ידע פרקטי ולא רק עם רשימה. רק זיכרו שיש עוד פתרונות רבים לבדיקות והפתרון שאני אציג הוא רק פתרון אחד. מה שכן, אין שום פתרון אחר לבדיקת פרונט אנד שהוא מוטמע בדרופל בצורת מודול.

Jasmine

סביבת הבדיקות שאני אדבר עליה היום היא jasmine. זו סביבת בדיקות ל-JavaScript שאפשר לנצל אותה גם כסביבת בדיקות פונקציונלית לווב. למה היא?
1. כי מאד מאד קל להתקין אותה ולהשתמש בה.
2. כי קיים מודול דרופלי שמממש אותה.

אז כמה מילים וקצת קוד על Jasmine ועל איך בודקים איתה JavaScript ו-web ואחרי זה אקשור את הכל לדרופל.

איך אני אדגים – באמצעות בדיקות לפלאגאין קטן של jQuery שכתבתי וכל מה שהוא עושה זה לפתוח תיבות. שם הפלאג אין הוא expanding box והקוד שלו זמין ב-gitHub.
דוגמה חיה לתוסף שממחישה כמה הוא פשוט נמצאת כאן.

בסך הכל מאוד מאוד פשוט. אני רוצה להכניס בדיקות אוטומטיות שיבדקו את ה-script המאד מאד פשוט הזה. איך אעשה את זה? באמצעות Jasmine. קודם כל אני צריך להתקין אותה.

איך מתקינים אותה? מאד מאד פשוט – מורידים את הקבצים של Jasmine SA ופורסים בשרת כלשהו – לצורך העניין אפילו WAMP או הדסקטופ שלנו.

אחרי שהתקנתי, אני אפתח, אחפש את specRunner,HTML שהוא הקובץ החשוב והמרכזי ואסתכל עליו.



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Jasmine Spec Runner</title>

  <link rel="shortcut icon" type="image/png" href="lib/jasmine-1.3.1/jasmine_favicon.png">
  <link rel="stylesheet" type="text/css" href="lib/jasmine-1.3.1/jasmine.css">
  
  <link rel="stylesheet" type="text/css" href="src/expanding_box.js">
  
  <script type="text/javascript" src="lib/jasmine-1.3.1/jasmine.js"></script>
  <script type="text/javascript" src="lib/jasmine-1.3.1/jasmine-html.js"></script>
  
  <!-- include source files here... -->
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
  <script type="text/javascript" src="src/expanding_box.js"></script>

  <!-- include spec files here... -->
  <script type="text/javascript" src="spec/SpecHelper.js"></script> <!-- for general functions -->
  <script type="text/javascript" src="spec/ExpandingBoxSpec.js"></script>

  <script type="text/javascript">
    (function() {
      var jasmineEnv = jasmine.getEnv();
      jasmineEnv.updateInterval = 1000;

      var htmlReporter = new jasmine.HtmlReporter();

      jasmineEnv.addReporter(htmlReporter);

      jasmineEnv.specFilter = function(spec) {
        return htmlReporter.specFilter(spec);
      };

      var currentWindowOnload = window.onload;

      window.onload = function() {
        if (currentWindowOnload) {
          currentWindowOnload();
        }
        execJasmine();
      };

      function execJasmine() {
        jasmineEnv.execute();
      }

    })();
  </script>

</head>

<body>
</body>
</html>

אני אראה שמדובר ב-HTML פשוט שבו אין לי מה לגעת וכמה src, אני אכלול ב-SRC הזה שלושה קבצים – הראשון הוא jQuery, כי מדובר בתוסף ל-jQuery. השני הוא קובץ התוסף, כי בסך הכל צריך לבדוק אותו והשלישי הוא קובץ הבדיקות שבו אני כותב את הבדיקות. ה-HTML הוא לא רלוונטי לשום דבר.

את jQuery אתם מכירים, את התוסף כבר יצא לכם לראות וראיתם כמה הוא פשוט, בוא ונסתכל על קובץ הבדיקות. גם הוא פשוט למדי.


describe("Expanding box jQuery plugin test", function() {

	beforeEach(function() {
		$('
').appendTo('body'); $('').appendTo('#container'); $('

Lorem Ipsum

').appendTo('#container'); $('.mybox h2').expanding_box(); }); it("Adding Class expanding button and more class to header", function() { expect($('h2.expanding_buttons.more').length).toEqual(1); }); it("Hide box content on start", function() { expect($('h2.expanding_buttons').nextAll(":visible").length).toEqual(0); }); it("clicking on header reveal box content", function() { $('#header').click(); expect($('h2.expanding_buttons').nextAll(":hidden").length).toEqual(0); }); it("clicking twice on header hide box content", function() { $('#header').click(); //first click setTimeout(function(){ $('#header').click(); //second click expect($('h2.expanding_buttons').nextAll(":visible").length).toEqual(0); }, 1); }); afterEach(function () { $("#container").remove(); }); });

ראשית,יש לנו describe שבו אנו רושמים את השם של סוויטת הבדיקות – השם הקולקטיבי של כל הבדיקות. אחר כך = פונקצית set up. פונקציה שרצה לפני כל בדיקה ובונה את סביבת העבודה שלי. במקרה הזה אני משתמש בה כדי ליצור אלמט HTMLי ולהפעיל את התוסף. בסוף יש פונקצית tear down שרצה אחרי כל בדיקה. שם אני מוחק את כל האלמנטים שנוצרו על ידי ה-setup.

ועכשיו כל מה שנותר לי לעשות זה לכתוב את הבדיקות – הנה הבדיקה הראשונה והנה הבדיקה השניה. אני לא נכנס לקוד אבל אפשר לראות כמה הוא פשוט – JavaScript פשוט שבפשוטים.

איך אני מריץ את הבדיקות האלו? פשוט נכנס אל specrunner ונותן לסקריפט לרוץ – בום! הנה התוצאה של כל הבדיקות

הנה דוגמה חיה ברשת – שימו לב שאין כאן דבר חוץ מה-specrunner והפניה לשלושת קבצי ה-JavaScript.. אתם יכולים לגשת ל-GitHub, להוריד משם את expanding box לשולחן העבודה שלכם, לפתוח את specRunner.html שנמצא בתיקית ה-test ולראות את אותו הדבר.

הסבר ומדריך יותר מקיף על Jasmine אפשר למצוא כאן.

Jasmine & Drupal – בדיקה ללא התקנת סביבה – באמעות המודול בלבד

טוב, עד כאן בנוגע ל-Jasmine. איך אני יכול להשתמש בה על מנת לבדוק את דרופל? בגדול זה די פשוט – כל מה שאני צריך לעשות זה להכניס לדרופל את קבצי jasmine וקבצי הבדיקות שלי ובכל פעם שאני רוצה להכנס לדף מסוים, אני אראה את תוצאות הבדיקות! זה כל כך פשוט שאפשר לעשות את זה גם באמצעות מודול פשוט שעושה drupal_add_js לקבצים הרלוונטיים. אני יכול ליצור למשל סט של בדיקות בסיסיות לכל אתרי הדרופל שלי בדפים שונים ובכל פעם שאני עושה ריפרש לדף מסוים לראות אם השינוי שלי שבר משהו בבדיקות.

אז כבר יש לנו בדיקות אוטומטיות. אנחנו יכולים בעצם להסתכל על כל דף ולראות אם כל הבדיקות שכתבנו ורצות על הדף הצליחו או לא הצליחו ואם שברנו משהו בכל פעם שאנחנו מרפרשים את העמוד.
אבל כאשר אנחנו יוצאים מתחום ה-hello world ועוברים לעולם האמיתי, יש לנו כמה בעיות בבדיקות אוטומטיות מהסוג הזה על דרופל. הבעיה המרכזית היא שלא כל דף זהה בתפקוד ובפונקציונליות שלו. לא בכל דף יש לי את המודול שאני רוצה לבדוק. למשל מודול ה-expanding box יהיה זמין בדף הראשי אבל לא בדף משתמש או דף פורומים (למשל).

בדיוק בשביל זה יצרתי את מודול jasmine drupal integration שכולל, חוץ מהוספת קבצי jasmine לדרופל, גם קובץ שנקרא מניפסט ובו אני קובע איזו בדיקה תרוץ איפה.

ואז אני יכול לעבור בין דפים שונים במערכת הדרופל שלי ולראות את התוצאות של הבדיקות בדפים השונים. כך אני יכול לקבוע שהבדיקות הקשורות למודול expanding box ירוצו בעמוד הבית ובו בלבד. תוצאות הבדיקות האלו יוצגו רק בעמוד הבית ויאפשרו לי לדעת בזמן אמת אם משהו נשבר ברגע ששיניתי משהו.

והנה דוגמה חיה למערכת דרופל שהותקן עליה המודול שכתבתי Jasmine. אנא היכנסו לדף הראשי ותיגללו כלפי מטה – תוכלו לראות תוצאה של בדיקה דיפולטיבית שהכנסתי שבודקת אם המודול פעיל.
אם תיכנסו לדף אחר במערכת, תוכלו לראות שהבדיקה לא מופיעה שם. כיוון שהמודול מאפשר לבחור, באמצעות קובץ מניפסט (קובץ JSON פשוט) איזה בדיקות ירוצו ואיפה. הבדיקה תרוץ אך ורק בדף הראשי כיוון שהגדרתי כך בקובץ.

Jasmine & Drupal עם phantomJS ו Drush לאוטומציה מלאה!

עד כאן זה סבבה. אבל זו לא ממש בדיקות אוטומטיות, לא? כי אני לא אעבור דף דף באופן ידני כאשר אני רוצה לבדוק שמשהו ששיניתי בדף א' לא שובר משהו בדף ב'. אני רוצה משהו שבאמצעות שורה אחת יבדוק את כל הדפים והבדיקות באמצעות המניפסט. אה, אם יש צורך בהכנסת שם משתמש הוא עושה את זה.

בדיוק בשביל זה מגיע המודול שלי שכולל אינטגרציה בין דרופל, jasmine ו-headless browser שנקרא phantomjs. מה זה headless browser? זה דפדפן שרץ על הקונסולה בלי אינפוט גרפי ומאפשר לי להריץ javascript עם dom בקלות והכי חשוב: במהירות. אני יכול להריץ המון המון בדיקות תוך זמן מאוד מאוד קצר. יתרון משמעותי לעומת סלניום או פתרונות אחרים.

המודול נכון להיום – מאפשר לעשות את זה על ידי אינטגרציה עם שני כלים. הראשון מהם הוא drush, תוסף לניהול והפעלת דרופל דרך שורת הפקודה של לינוקס והשני הוא phantomjs שכפי שציינתי זה headless browser מהיר במיוחד שמרנדר את הדפים ומריץ עליהם את הבדיקות דרך הקונסולה ללא צורך בדפדפן 'אמיתי'.

על מנת להריץ את כל הבדיקות בשורה אחת אני צריך להתקין drush ו phantomjs. מאוד מאוד קל לעשות את זה. אני צריך להכנס לתוך מסך הגדרות המודול ולהגדיר שלושה דברים:

ממשק הניהול של Jasmine Drupal
ממשק הניהול של Jasmine Drupal

1. כתובת האתר שלי – הכתובת שה-phantomJS נכנס אליה.
2. שם משתמש, במידה ואני רוצה לבדוק דפים שיש בהם צורך ברישום.
3. סיסמה.

עכשיו, כל מה שיש לי לעשות זה לוודא שכל הבדיקות מוגדרות היטב במניפסט – כך הקובץ נראה!


{
    "drupal_is_front_page()":
    {"tests":["sites/all/modules/drupal_jasmine_integration/js"],
    "url":"",
    "registered":0},
	"drupal_is_front_page()":
    {"tests":["sites/all/modules/drupal_jasmine_integration/js"],
    "url":"",
    "registered":1}
}

ראשית אני אגדיר בקובץ המניפסט את הבדיקה שצריך לעשות כאשר אני מכניס שלושה פרמטרים: תיקית המודול, ה-URL שה-phantomJS צריך ותנאי מסוים שצריך להתקיים על מנת שהבדיקה תרוץ וכמובן אם המשתמש הוא registered.

אחרי כן אני פשוט מריץ את פקודת ה-drush המאוד מאוד פשוטה הזו:

בהרצה הזו הרצתי רק שתי בדיקות בלבד – אחת עבור משתמש אנונימי והשניה עבור משתמש רשום. בסביבה שלנו ב-HPLN אני מריץ עשרות בדיקות תוך כמה שניות בודדות.

עבודה עם ה-phantom זה כבר כמובן טיפה יותר מסובך כי אני צריך לינוקס שמריץ את דרופל, להתקין את phantomjs ואת drush ולדעת להריץ אותם. אבל כאמור – לא חייבים את זה. המודול מאפשר הצגה של התוצאות בכל דף ללא התקנות או שורת פקודה. אם אתם רוצים מעבר – אז כן – חייבים להתקין לפחות מכונת לינוקס אחת שתעבוד על זה.

דרופל נכון להיות היא איומה לבדיקות. אין לנו יכולת לעשות לה Unit testing אמיתי והבדיקות העיקריות שאנו יכולים לעשות הן בדיקות פונקציונליות. נכון להיות יש מספר כלים פונקציונליים לבדיקות כלליות – סלניום היא דוגמה טובה, או מספר מוצרים ש-HP מייצרת. אבל אפשר גם להשתמש בכלים אחרים כמו selenium שעובדת יפה עם דרופל.

המודול שלי, שמבצע את האינטגרציה הזו ומאפשר בדיקות אוטומטית מופיע ב-github וניתן בהחלט להוריד אותו ולהתנסות או אף לסייע בתהליך הפיתוח.

פוסטים נוספים שכדאי לקרוא

גלילה לראש העמוד