<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: tony</title>
    <description>The latest articles on Forem by tony (@tonyfrenzy).</description>
    <link>https://forem.com/tonyfrenzy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F228857%2Fbd72e4fa-9d7e-47a5-8152-fa48a8a5327b.jpeg</url>
      <title>Forem: tony</title>
      <link>https://forem.com/tonyfrenzy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tonyfrenzy"/>
    <language>en</language>
    <item>
      <title>Laravel on Steroids! Get 10x Speed in Your App Development</title>
      <dc:creator>tony</dc:creator>
      <pubDate>Mon, 30 Sep 2019 15:42:59 +0000</pubDate>
      <link>https://forem.com/tonyfrenzy/laravel-on-steriods-get-10x-speed-in-your-app-development-2lp3</link>
      <guid>https://forem.com/tonyfrenzy/laravel-on-steriods-get-10x-speed-in-your-app-development-2lp3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cMNC-HzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-4tkPoZdF-zc/XZIfBTuMnZI/AAAAAAAAAgo/NPizhwybyZE3oDtAbzt-EbmEgKrjwjKTgCLcBGAsYHQ/s1600/laravel-on-steroids.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cMNC-HzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-4tkPoZdF-zc/XZIfBTuMnZI/AAAAAAAAAgo/NPizhwybyZE3oDtAbzt-EbmEgKrjwjKTgCLcBGAsYHQ/s1600/laravel-on-steroids.jpg" alt="Laravel on Steroids"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://www.columbusrecoverycenter.com/blog/ohio-residents-ask-are-anabolic-steroids-addictive/"&gt;Source&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  - DB-MVCr-MPR-TA
&lt;/h1&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>laravel</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Part 3: Testing Model Relationships in Laravel — POLYMORPHIC</title>
      <dc:creator>tony</dc:creator>
      <pubDate>Sun, 29 Sep 2019 16:27:49 +0000</pubDate>
      <link>https://forem.com/tonyfrenzy/part-3-testing-model-relationships-in-laravel-polymorphic-m51</link>
      <guid>https://forem.com/tonyfrenzy/part-3-testing-model-relationships-in-laravel-polymorphic-m51</guid>
      <description>&lt;h3&gt;
  
  
  Part 3: Testing Model Relationships in Laravel — POLYMORPHIC
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A6NdGWcFOM1jbb--dAcZnQQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A6NdGWcFOM1jbb--dAcZnQQ.png"&gt;&lt;/a&gt;Source: &lt;a href="https://medium.com/better-through-code?source=post_page-----2894f43217e4----------------------" rel="noopener noreferrer"&gt;Better Through Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This part deals with more complex model relationships, the polymorphic type. Just like before, we shall stick to the official documentation examples and work out befitting tests. To have a low down on the earlier parts see link directly below 👇&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part 1: &lt;a href="https://dev.to/tonyfrenzy/part-1-testing-model-relationships-in-laravel-schema-tests-37nj"&gt;&lt;strong&gt;Intro and Schema Tests&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 2: &lt;a href="https://dev.to/tonyfrenzy/part-2-testing-model-relationships-in-laravel-basic-3a44"&gt;&lt;strong&gt;Testing Basic Model Relationships&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 3: &lt;strong&gt;Testing Polymorphic Relationships&lt;/strong&gt; ⏯&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  POLYMORPHIC RELATIONSHIPS
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A polymorphic relationship allows a target model to belong to more than one type of model using a single association.&lt;/strong&gt;  — &lt;a href="https://laravel.com/docs/6.x/eloquent-relationships#polymorphic-relationships" rel="noopener noreferrer"&gt;Laravel.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. One-to-One Polymorphic Relationship
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A one-to-one polymorphic relation is similar to a simple one-to-one relation; however, the target model can belong to more than one type of model on a single association.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Scenario:
&lt;/h4&gt;

&lt;p&gt;A blog Post and a User may share a polymorphic relation to an Image model. Using a one-to-one polymorphic relation allows you to have a single list of unique images that are used for both blog &lt;strong&gt;&lt;em&gt;post&lt;/em&gt;&lt;/strong&gt; s and &lt;strong&gt;&lt;em&gt;user&lt;/em&gt;&lt;/strong&gt;  accounts&lt;/p&gt;

&lt;h4&gt;
  
  
  morphTo()
&lt;/h4&gt;

&lt;p&gt;— An image table can be &lt;strong&gt;&lt;em&gt;morph&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;ed&lt;/em&gt; in &lt;strong&gt;&lt;em&gt;to&lt;/em&gt;&lt;/strong&gt; any model (i.e serve many different models), eg User or Post model in our case.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Image.php
...
public function imageable() 
{ 
 return $this-&amp;gt;morphTo(); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h4&gt;
  
  
  morphOne()
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;— A user/post model can &lt;strong&gt;&lt;em&gt;morph one&lt;/em&gt;&lt;/strong&gt; instance of the same image model table (i.e make use of same image table but &lt;strong&gt;one&lt;/strong&gt; record per user/post).&lt;/li&gt;
&lt;li&gt;— INVERSE of &lt;strong&gt;&lt;em&gt;morphTo&lt;/em&gt;&lt;/strong&gt; relationship.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/User.php
...
public function image() 
{ 
 return $this-&amp;gt;morphOne(Image::class, 'imageable'); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Files relevant to this test 👇&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

- **MODEL FILES(App/)
 -- User.php 
 -- Post.php
 -- Image.php

- **MIGRATION FILES(database/migrations/)
 -- 2014\10\12\000000\create\users\table.php
 -- 2019\09\27\100604\create\posts\table.php
 -- 2019\09\28\143143\create\images\table.php

- **MODEL FACTORY FILES(database/factories/)
 -- UserFactory.php 
 -- PostFactory.php
 -- ImageFactory.php

- **UNIT TEST FILES(tests/Units/)
 -- UserTest.php 
 -- PostsTest.php
 -- ImagesTest.php


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  2. One-to-Many (Polymorphic)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A “one-to-many polymorphic” relation is similar to a simple one-to-many relation; however, the target model can belong to more than one type of model on a single association. — &lt;a href="https://laravel.com/docs/6.x/eloquent-relationships#one-to-many-polymorphic-relations" rel="noopener noreferrer"&gt;Laravel.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Scenario:
&lt;/h4&gt;

&lt;p&gt;Users of your application can “comment” on both posts and videos. Using polymorphic relationships, you may use a single comments table for both of these scenarios.&lt;/p&gt;
&lt;h4&gt;
  
  
  morphTo()
&lt;/h4&gt;

&lt;p&gt;— A comment table can be &lt;strong&gt;&lt;em&gt;morph&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;ed&lt;/em&gt; &lt;strong&gt;&lt;em&gt;to&lt;/em&gt;&lt;/strong&gt; any model (i.e serve many different models), eg Video or Post model in our case.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Comment.php
...
public function commentable() 
{ 
 return $this-&amp;gt;morphTo(); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h4&gt;
  
  
  morphMany()
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;— A video/post model can &lt;strong&gt;&lt;em&gt;morph many&lt;/em&gt;&lt;/strong&gt; instances of the same comment model table (i.e make use of same comment table for many records).&lt;/li&gt;
&lt;li&gt;— INVERSE of &lt;strong&gt;&lt;em&gt;morphTo&lt;/em&gt;&lt;/strong&gt; relationship.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Video.php
...
public function comments() 
{ 
 return $this-&amp;gt;morphMany(Comment::class, 'commentable'); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Files relevant to this test 👇&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;**MODEL FILES(App/)&lt;br&gt;
-- User.php &lt;br&gt;
-- Post.php&lt;br&gt;
-- Video.php&lt;br&gt;
-- Comment.php&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**MIGRATION FILES(database/migrations/)&lt;br&gt;
-- 2019\09\28\211240\create\videos\table.php&lt;br&gt;
-- 2019\09\28\221627\add\commentable\id\and\commentable\type\to\comments\table.php&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**MODEL FACTORY FILES(database/factories/)&lt;br&gt;
-- VideoFactory.php&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**UNIT TEST FILES(tests/Unit/)&lt;br&gt;
-- PostsTest.php&lt;br&gt;
-- VideosTest.php&lt;br&gt;
-- CommentsTest.php&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  

&lt;ol&gt;
&lt;li&gt;Many-to-Many (Polymorphic)
&lt;/li&gt;
&lt;/ol&gt;
&lt;/h3&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In progress…&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Kindly check back soon
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;👉Part 1: &lt;a href="https://dev.to/tonyfrenzy/part-1-testing-model-relationships-in-laravel-schema-tests-37nj"&gt;&lt;strong&gt;Intro and Schema Tests&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👉Part 2: &lt;a href="https://dev.to/tonyfrenzy/part-2-testing-model-relationships-in-laravel-basic-3a44"&gt;&lt;strong&gt;Testing Basic Model Relationships&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⏯Part 3: &lt;strong&gt;Testing Polymorphic Relationships&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>eloquentorm</category>
      <category>laravel</category>
      <category>codequality</category>
      <category>phpunit</category>
    </item>
    <item>
      <title>Part 2: Testing Model Relationships in Laravel — BASIC</title>
      <dc:creator>tony</dc:creator>
      <pubDate>Sun, 29 Sep 2019 16:20:23 +0000</pubDate>
      <link>https://forem.com/tonyfrenzy/part-2-testing-model-relationships-in-laravel-basic-3a44</link>
      <guid>https://forem.com/tonyfrenzy/part-2-testing-model-relationships-in-laravel-basic-3a44</guid>
      <description>&lt;h3&gt;
  
  
  Part 2: Testing Model Relationships in Laravel — BASIC
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AhEH7jGETW9HaKrcKweyoRw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AhEH7jGETW9HaKrcKweyoRw.png"&gt;&lt;/a&gt;Some Laravel model relationship unit tests&lt;/p&gt;

&lt;p&gt;100% code coverage is hardly achievable in code testing, we do aim closer but some tests are really boring. In this multipart post &lt;strong&gt;I helped you edge closer to 100% code coverage by writing some 5%&lt;/strong&gt; of the tests you need in all your Laravel apps — the boring and often overlooked tests.&lt;br&gt;&lt;br&gt;
Eloquent relationships are ever present in every Laravel app but how do you ensure the expected models are all connected? &lt;strong&gt;&lt;em&gt;This could be your cheatsheet for eloquent relationship tests&lt;/em&gt;&lt;/strong&gt;. We are going to write tests that ensure all our models have relevant model connections and that they are correctly set.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part 1: &lt;a href="https://dev.to/tonyfrenzy/part-1-testing-model-relationships-in-laravel-schema-tests-37nj"&gt;&lt;strong&gt;Intro and Schema Tests&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 2: &lt;strong&gt;Testing Basic Model Relationships&lt;/strong&gt; ⏯&lt;/li&gt;
&lt;li&gt;Part 3: &lt;a href="https://dev.to/tonyfrenzy/part-3-testing-model-relationships-in-laravel-polymorphic-m51"&gt;&lt;strong&gt;Testing Polymorphic Relationships&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  THE RELATIONSHIPS
&lt;/h3&gt;

&lt;p&gt;The word &lt;strong&gt;relationship&lt;/strong&gt; is expected to involve at least two entities, thus every eloquent relationship has two parties, (a). &lt;strong&gt;&lt;em&gt;The first&lt;/em&gt;&lt;/strong&gt; relationship and (b). &lt;strong&gt;&lt;em&gt;The Inverse&lt;/em&gt;&lt;/strong&gt; relationship (either of the models could be made the &lt;em&gt;first&lt;/em&gt; but a &lt;em&gt;more influential&lt;/em&gt; or &lt;em&gt;parent-esque&lt;/em&gt; model is okay as the first). As we write model relationship tests it is only right to test from the two concerned ends, thus we shall be writing for both first and inverse relationships.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In mosts cases, &lt;a href="https://laravel.com/docs/6.x/eloquent-relationships" rel="noopener noreferrer"&gt;relationship examples&lt;/a&gt; used in the official Laravel documentation will be used in this post. Your use-cases may be different, simply adapt the tests to your specific scenario.&lt;/li&gt;
&lt;li&gt;there are places where I included more than one method of testing, any of them is just fine.&lt;/li&gt;
&lt;li&gt;Watch out! Whenever a new model is introduced I add a schema test. Do not be surprised if some files have more test than others.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  1. One To One Relationship
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A one-to-one relationship is used to define relationships where a single model has a unary relationship with another model. Both models can own only one instance of the each other.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Scenario:
&lt;/h4&gt;

&lt;p&gt;We have &lt;strong&gt;User&lt;/strong&gt; and &lt;strong&gt;Phone&lt;/strong&gt; models. A user is allowed to register only one phone number on the app, this means one unique phone entry for a given user in the phone table. This relationship can pan out as &lt;strong&gt;hasOne()&lt;/strong&gt; and &lt;strong&gt;belongsTo()&lt;/strong&gt; relationships.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;hasOne()&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;— A user &lt;strong&gt;&lt;em&gt;has one&lt;/em&gt;&lt;/strong&gt; phone registered (FIRST).&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/User.php
...
public function phone() 
{ 
 return $this-\&amp;gt;hasOne(Phone::class); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;THE TEST&lt;/strong&gt; : A user owns a phone, a phone is a unique entity thus we test that the phone is an &lt;strong&gt;&lt;em&gt;instanceOf&lt;/em&gt;&lt;/strong&gt; a Phone class. Second method tests existence of a relationship by asserting with a successful count.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;belongsTo()&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;— Any registered phone &lt;strong&gt;&lt;em&gt;belongs to&lt;/em&gt;&lt;/strong&gt; a single user&lt;/li&gt;
&lt;li&gt;— INVERSE of &lt;strong&gt;&lt;em&gt;hasOne&lt;/em&gt;&lt;/strong&gt; relationship.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Phone.php  
...
public function user() 
{ 
 return $this-\&amp;gt;belongsTo(User::class); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;THE TEST&lt;/strong&gt; : A phone belongs to a user, a user is a unique entity thus we tested that a user is an &lt;strong&gt;&lt;em&gt;instanceOf&lt;/em&gt;&lt;/strong&gt; a User class.&lt;/p&gt;

&lt;p&gt;Files relevant to this test 👇&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

- **MODEL FILES** (App/)
 -- User.php 
 -- Phone.php

- **MIGRATION FILES** (database/migrations/)
 -- 2014\10\12\000000\create\users\table.php
 -- 2019\09\26\154439\create\phones\table.php

- **MODEL FACTORY FILES** (database/factories/)
 -- UserFactory.php 
 -- PhoneFactory.php

- **UNIT TEST FILES** (tests/Units/)
 -- UserTest.php 
 -- PhonesTest.php


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Simply run the test suite and you should get a green.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ pu or putu (or any nice alias you gave to your unit test commands)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or &lt;code&gt;$ vendor/bin/phpunit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F720%2F1%2Az_G8V3yyXpVZMkYVcI4qKQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F720%2F1%2Az_G8V3yyXpVZMkYVcI4qKQ.png"&gt;&lt;/a&gt;All tests passed&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5 tests?&lt;/strong&gt; Yeah, schema test inclusive. See the list below:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

1. User schema test 
2. Phone schema test
3. User-\&amp;gt;hasOne(phone) test (2 methods)
4. Phone-\&amp;gt;belongsTo(user) test


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Tweak your code, goof around. Just have fun.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. One To Many Relationship
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A one-to-many relationship is used to define relationships where a single model owns any amount of other models. — &lt;a href="https://laravel.com/docs/6.x/eloquent-relationships#one-to-many" rel="noopener noreferrer"&gt;Laravel.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Scenario:
&lt;/h4&gt;

&lt;p&gt;A blog &lt;strong&gt;&lt;em&gt;post&lt;/em&gt;&lt;/strong&gt; with an infinite number of &lt;strong&gt;&lt;em&gt;comments&lt;/em&gt;&lt;/strong&gt; or an author (user) with many articles or comments. We are going to write a test for &lt;strong&gt;Post&lt;/strong&gt; and &lt;strong&gt;Comment&lt;/strong&gt; models relationship. Thus this relationship can pan out as &lt;strong&gt;hasMany()&lt;/strong&gt; and &lt;strong&gt;belongsTo()&lt;/strong&gt; relationships.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;hasMany()&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;— A post &lt;strong&gt;&lt;em&gt;has many&lt;/em&gt;&lt;/strong&gt; comments on it (FIRST).&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Post.php
...
public function comments() 
{ 
 return $this-\&amp;gt;hasMany(Comment::class); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;THE TEST&lt;/strong&gt; : Since a post has many comments, the comments are returned as collections on the &lt;strong&gt;&lt;em&gt;post instance&lt;/em&gt;&lt;/strong&gt; that is why we are able to do iterations when rendering results in app views. It is correct that we test a post’s comments as an &lt;strong&gt;&lt;em&gt;instanceOf&lt;/em&gt;&lt;/strong&gt; a collection.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;belongsTo()&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;— A comment &lt;strong&gt;&lt;em&gt;belongs to&lt;/em&gt;&lt;/strong&gt; a post&lt;/li&gt;
&lt;li&gt;— INVERSE of &lt;strong&gt;&lt;em&gt;hasMany&lt;/em&gt;&lt;/strong&gt; relationship.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Comment.php
...
public function user() 
{ 
 return $this-\&amp;gt;belongsTo(Post::class); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;THE TEST&lt;/strong&gt; : A comment belongs to a post, a post is a unique entity thus we test that a post is an &lt;strong&gt;&lt;em&gt;instanceOf&lt;/em&gt;&lt;/strong&gt; a Post class. This is similar to $phone-&amp;gt;user test we had earlier.&lt;/p&gt;

&lt;p&gt;Files relevant to this test 👇&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

- **MODEL FILES** (App/)
 -- User.php 
 -- Post.php
 -- Comment.php

- **MIGRATION FILES** (database/migrations/)
 -- 2014\10\12\000000\create\users\table.php
 -- 2019\09\27\100604\create\posts\table.php
 -- 2019\09\27\100620\create\comments\table.php

- **MODEL FACTORY FILES** (database/factories/)
 -- UserFactory.php 
 -- PostFactory.php
 -- CommentFactory.php

- **UNIT TEST FILES** (tests/Units/)
 -- UserTest.php 
 -- PostsTest.php
 -- CommentsTest.php


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;If you run the test at this point it should all pass.&lt;/p&gt;
&lt;h4&gt;
  
  
  Heads up:
&lt;/h4&gt;

&lt;p&gt;As depicted in the scenario section, this same &lt;strong&gt;One To Many&lt;/strong&gt; tests can be replicated on &lt;strong&gt;&lt;em&gt;User-Post&lt;/em&gt;&lt;/strong&gt; , &lt;strong&gt;&lt;em&gt;User-Comment&lt;/em&gt;&lt;/strong&gt; and other model relationships that fit into the scenario &lt;em&gt;(I have all the tests in this&lt;/em&gt; &lt;strong&gt;&lt;em&gt;Github repo&lt;/em&gt;&lt;/strong&gt; )_. A user can create many posts and many comments as well, these are &lt;strong&gt;hasMany()&lt;/strong&gt; relationships. Writing model relationship tests will become natural to you when you fully understand how the eloquent relationships work.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Many-to-Many Relationship
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A many-to-many relationship is used to define relationships where the two models involved can have many instances of each other.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Scenario:
&lt;/h4&gt;

&lt;p&gt;A user can play many roles, and the roles are also shared by other users. Also for doctors and medical specialties, a specialty can be shared by many doctors while a doctor can be specialized in many specialties. Our test will be for &lt;strong&gt;User&lt;/strong&gt; and &lt;strong&gt;Role&lt;/strong&gt; models relationship.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;belongsTo&lt;/em&gt;&lt;/strong&gt; means a model that is already existing that another model fits into but have no privilege to create. This is different from &lt;em&gt;hasOne&lt;/em&gt; or &lt;em&gt;hasMany&lt;/em&gt; whose verb depict that a given model owns or creates another. On both models involved, the relationship is defined as &lt;strong&gt;belongsToMany()&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  belongsToMany()
&lt;/h4&gt;

&lt;p&gt;— A user &lt;strong&gt;&lt;em&gt;belongs to many&lt;/em&gt;&lt;/strong&gt; roles (FIRST).&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/User.php
...
public function roles() 
{ 
 return $this-\&amp;gt;belongsToMany(Comment::class); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h4&gt;
  
  
  belongsToMany()
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;— A role &lt;strong&gt;&lt;em&gt;belongs to many&lt;/em&gt;&lt;/strong&gt;  users&lt;/li&gt;
&lt;li&gt;— INVERSE of &lt;strong&gt;&lt;em&gt;belongsToMany&lt;/em&gt;&lt;/strong&gt; relationship. Kinda recursive.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Role.php
...
public function users() 
{ 
 return $this-\&amp;gt;belongsToMany(User::class); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NB&lt;/strong&gt; : &lt;strong&gt;&lt;em&gt;role\user&lt;/em&gt;&lt;/strong&gt; table must be migrated for this tests to pass.&lt;/p&gt;

&lt;p&gt;Files relevant to this test 👇&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

- **MODEL FILES** (App/)
 -- User.php 
 -- Role.php

- **MIGRATION FILES** (database/migrations/)
 -- 2014\10\12\000000\create\users\table.php
 -- 2019\09\27\155312\create\roles\table.php
 -- 2019\09\27\164342\create\role\user\table.php

- **MODEL FACTORY FILES** (database/factories/)
 -- UserFactory.php 
 -- RoleFactory.php

- **UNIT TEST FILES** (tests/Units/)
 -- UserTest.php 
 -- RolesTest.php


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  4. Has One Through Relationship
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The “&lt;a href="https://laravel.com/docs/6.x/eloquent-relationships#has-one-through" rel="noopener noreferrer"&gt;has-one-through&lt;/a&gt;” relationship links models through a single intermediate relation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Scenario:
&lt;/h4&gt;

&lt;p&gt;Given a &lt;strong&gt;Supplier&lt;/strong&gt; has one &lt;strong&gt;User&lt;/strong&gt; , and each user is associated with a user &lt;strong&gt;History&lt;/strong&gt; record, the supplier model may access the user’s history &lt;em&gt;through&lt;/em&gt; the intermediate user model.&lt;/p&gt;
&lt;h4&gt;
  
  
  hasOneThrough()
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;— A supplier &lt;strong&gt;&lt;em&gt;has one&lt;/em&gt;&lt;/strong&gt; history &lt;strong&gt;&lt;em&gt;through&lt;/em&gt;&lt;/strong&gt; a user&lt;/li&gt;
&lt;li&gt;— has no official INVERSE relationship.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Supplier.php
...
public function userHistory() 
{ 
 return $this-\&amp;gt;hasOneThrough(History::class, User::class); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The “ &lt;strong&gt;&lt;em&gt;hasThrough&lt;/em&gt;&lt;/strong&gt; ” relationships do not have official reverse relationship since the concerned models are always indirectly related but a reverse can be hacked by linking through the intermediate model like below, however, beware of n+1 issues and eager load as appropriate.:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/History.php
...
/** 
 * With this attribute defined it can be used as **$this-\&amp;gt;supplier**
 */
public function getSupplierAttribute()
{
 return $this-\&amp;gt;user-\&amp;gt;supplier;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Files relevant to this test 👇&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

- **MODEL FILES** (App/)
 -- User.php 
 -- Supplier.php
 -- History.php

- **MIGRATION FILES** (database/migrations/)
 -- 2014\10\12\000000\create\users\table.php
 -- 2019\09\27\155312\create\roles\table.php
 -- 2019\09\27\164342\create\role\user\table.php

- **MODEL FACTORY FILES** (database/factories/)
 -- UserFactory.php 
 -- SuppliersFactory.php
 -- HistoryFactory.php

- **UNIT TEST FILES** (tests/Units/)
 -- UserTest.php 
 -- SuppliersTest.php
 -- HistoriesTest.php


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  5. Has Many Through Relationship
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Just like the “has-one-through” relationship links a distant related model through an intermediate relation, “ &lt;a href="https://laravel.com/docs/6.x/eloquent-relationships#has-many-through" rel="noopener noreferrer"&gt;has-many-through&lt;/a&gt;” does same but it &lt;strong&gt;can reference many instances&lt;/strong&gt; of the distant related model.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Scenario:
&lt;/h4&gt;

&lt;p&gt;A Country model might have many Post models through an intermediate User model. We will write a test that ensures blog posts for a given country can be accessed on the country instance by a &lt;strong&gt;&lt;em&gt;hasManyThrough&lt;/em&gt;&lt;/strong&gt; relationship.&lt;/p&gt;
&lt;h4&gt;
  
  
  hasManyThrough()
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;— A country can &lt;strong&gt;&lt;em&gt;have many&lt;/em&gt;&lt;/strong&gt; posts &lt;strong&gt;&lt;em&gt;through&lt;/em&gt;&lt;/strong&gt; a user model&lt;/li&gt;
&lt;li&gt;— has no official REVERSE relationship&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Country.php
...
public function posts() 
{ 
 return $this-\&amp;gt;hasManyThrough(Post::class, User::class); 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NB:&lt;/strong&gt; We now make use of a parent::setup() method to DRY the test codes.&lt;/p&gt;

&lt;p&gt;The “ &lt;strong&gt;&lt;em&gt;hasThrough&lt;/em&gt;&lt;/strong&gt; ” relationships do not have official reverse relationship but a reverse can be hacked by linking through the intermediate model like below, (beware of n+1 issues and eager load as appropriate):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// App/Post.php
...
/** 
 * With this attribute defined it can be used as **$this-\&amp;gt;country**
 */
public function getCountryAttribute()
{
 return $this-\&amp;gt;user-\&amp;gt;country;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Files relevant to this test 👇&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

- **MODEL FILES** (App/)
 -- User.php 
 -- Country.php
 -- Post.php

- **MIGRATION FILES** (database/migrations/)
 -- 2014\10\12\000000\create\users\table.php
 -- 2019\09\27\100604\create\posts\table.php
 -- 2019\09\28\130218\create\countries\table.php
 -- 2019\09\28\131328\add\country\id\to\users\table.php

- **MODEL FACTORY FILES** (database/factories/)
 -- UserFactory.php 
 -- CountryFactory.php
 -- PostFactory.php

- **UNIT TEST FILES** (tests/Units/)
 -- UserTest.php 
 -- CountriesTest.php
 -- PostsTest.php


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;See the polymorphic relationship tests in the next post.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👉Part 1: &lt;a href="https://dev.to/tonyfrenzy/part-1-testing-model-relationships-in-laravel-schema-tests-37nj"&gt;&lt;strong&gt;Intro and Schema Tests&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⏯Part 2: &lt;strong&gt;Testing Basic Model Relationships&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;👉Part 3: &lt;a href="https://dev.to/tonyfrenzy/part-3-testing-model-relationships-in-laravel-polymorphic-m51"&gt;&lt;strong&gt;Testing Polymorphic Relationships&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>laravel</category>
      <category>unittesting</category>
      <category>php</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Part 1: Testing Model Relationships in Laravel — Schema Tests</title>
      <dc:creator>tony</dc:creator>
      <pubDate>Sun, 29 Sep 2019 16:13:24 +0000</pubDate>
      <link>https://forem.com/tonyfrenzy/part-1-testing-model-relationships-in-laravel-schema-tests-37nj</link>
      <guid>https://forem.com/tonyfrenzy/part-1-testing-model-relationships-in-laravel-schema-tests-37nj</guid>
      <description>&lt;h3&gt;
  
  
  Part 1: Testing Model Relationships in Laravel — Schema Tests
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVKkxNdeOKPu2SDklt6cs1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVKkxNdeOKPu2SDklt6cs1w.png"&gt;&lt;/a&gt;Laravel Database Designer — &lt;a href="https://biodesign.cc/2015/03/10/laravel-database-designer/" rel="noopener noreferrer"&gt;Biodesign.cc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Laravel makes TDD a lot more fun, it is such a joy to work with .&lt;/strong&gt; The essence of the tests in this series is to ensure that your app model relationship is not missing a bolt. The code snippets will be available for easy reach at this &lt;a href="https://github.com/tonyfrenzy/laravel-model-relationship-tests" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Github project link&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Table of contents
&lt;/h3&gt;

&lt;p&gt;To make this post more organized it will be split into three (3) parts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part 1: &lt;strong&gt;Intro and Schema Tests&lt;/strong&gt;  ⏯&lt;/li&gt;
&lt;li&gt;Part 2: &lt;a href="https://dev.to/tonyfrenzy/part-2-testing-model-relationships-in-laravel-basic-3a44"&gt;&lt;strong&gt;Testing Basic Model Relationships&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 3: &lt;a href="https://dev.to/tonyfrenzy/part-3-testing-model-relationships-in-laravel-polymorphic-m51"&gt;&lt;strong&gt;Testing Polymorphic Relationships&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing tests make your code rock solid, predictable and highly maintainable. I have written some terrible apps in the past and it can be unnerving when broken codes scream &lt;strong&gt;in — y o u r — face&lt;/strong&gt;. Those years I had no clue about unit tests — fix one bug and another one surfaces, more annoying is that you don’t know when another will pop up. Errors are bound to occur if relevant models are missing or wrongly connected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unit and Feature Tests
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Unit Tests&lt;/strong&gt; are written for small pieces of a code base such as methods or attributes in a class. It usually deals with testing fine details at low level only. In our case we will be testing some methods on Laravel model classes, that is, model connections and relationships between different parts of an app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature Tests&lt;/strong&gt; is more encompassing as it sums up different part of a code and tests how well they inter-operate eg functional tests and integration tests on components, modules etc. We are not going into functional test in this post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NB:&lt;/strong&gt; &lt;em&gt;it is assumed that you have a working knowledge of Laravel, therefore nitty gritty of&lt;/em&gt; &lt;a href="https://laravel.com/docs/6.x/installation" rel="noopener noreferrer"&gt;&lt;em&gt;installation&lt;/em&gt;&lt;/a&gt;&lt;em&gt;,&lt;/em&gt; &lt;a href="https://laravel.com/docs/6.x/eloquent" rel="noopener noreferrer"&gt;&lt;em&gt;eloquent model&lt;/em&gt;&lt;/a&gt; &lt;em&gt;setup and&lt;/em&gt; &lt;a href="https://laravel.com/docs/6.x/eloquent-relationships" rel="noopener noreferrer"&gt;&lt;em&gt;relationship&lt;/em&gt;&lt;/a&gt; &lt;em&gt;are not discussed. However, test relevant topics will be discussed in depth.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To&lt;/strong&gt; &lt;a href="https://laravel.com/docs/6.x/installation" rel="noopener noreferrer"&gt;&lt;strong&gt;install a new laravel app&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;laravel new modelRelTests&lt;/code&gt; via &lt;strong&gt;&lt;em&gt;installer&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;composer create-project --prefer-dist laravel/laravel modelRelTests&lt;/code&gt; via &lt;strong&gt;&lt;em&gt;create-project&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Set Up Test Suite
&lt;/h3&gt;

&lt;p&gt;We are going to make use of an sqlite database and use it in memory for faster test runs. Go to phpunit.xml at the root directory of your application and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
&amp;lt;server name=" **DB\_CONNECTION**" value=" **sqlite**"/&amp;gt;
&amp;lt;server name=" **DB\_DATABASE**" value=" **:memory:**"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2. Creating a Test Class
&lt;/h3&gt;

&lt;p&gt;If we run &lt;code&gt;vendor/bin/phpunit&lt;/code&gt; at this point we get 2 tests for the dummy tests added by Laravel, one test each in the Unit and Feature test directories. Seeing the green is refreshing. You should delete the two files in preparation for our real tests.&lt;/p&gt;

&lt;p&gt;By default, every new Laravel installation comes with a &lt;strong&gt;User model&lt;/strong&gt; class (along with migration, controller etc) but not a test. We should create our own test file with the command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:test **UserTest --unit**&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This creates a test file named &lt;strong&gt;UserTest.php&lt;/strong&gt; within the &lt;strong&gt;&lt;em&gt;tests/Unit&lt;/em&gt;&lt;/strong&gt; directory in the root folder. The &lt;code&gt;--unit flag&lt;/code&gt; implies that we are creating a unit test and should add the generated file to the unit test directory. Without the &lt;code&gt;--unit flag&lt;/code&gt; we have a feature test and it gets added to &lt;strong&gt;&lt;em&gt;tests/Feature&lt;/em&gt;&lt;/strong&gt; directory.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Schema Test — My First Test in Every Model
&lt;/h3&gt;

&lt;p&gt;Before visiting model relationship tests, my very first unit test in every Laravel model is the &lt;strong&gt;schema test&lt;/strong&gt;. We can use this test to ensure that relevant table columns are not missing and also have the correct and expected &lt;strong&gt;names&lt;/strong&gt;. All we need to do is this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Take note of :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;use Illuminate\Support\Facades\Schema;&lt;/code&gt; namespace.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RefreshDatabase&lt;/code&gt; and &lt;code&gt;WithFaker&lt;/code&gt; traits. These two traits are important in most tests since you will most likely need a database of data to test your models and the faker library to populate a database with data to be tested upon.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to be explicit about your schema checks you may check each individual field with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;...Schema:: **hasColumn** ('model', **'column'** ), 1);&lt;/code&gt; instead of&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;...Schema:: **hasColumns** ('model', **['column\_1', 'column\_2']**), 1);&lt;/code&gt; which checks all columns existence at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I prefer &lt;code&gt;**hasColumns()**&lt;/code&gt; though, odd part is that you get a general error report and so don’t know the actual column affected unless you check thoroughly.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;vendor/bin/phpunit&lt;/code&gt; and see the result below 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A6sI2CZSLfC4z1dMb9oLR-A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A6sI2CZSLfC4z1dMb9oLR-A.png"&gt;&lt;/a&gt;TDD — failed because database is not set&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;This test failed, why?&lt;/em&gt;&lt;/strong&gt; We have not set up or created our database yet. Set up your database configurations within the &lt;code&gt;.env&lt;/code&gt; file according to your machine. See the snippet below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB\_DATABASE=homestead
DB\_USERNAME=homestead
DB\_PASSWORD=secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create your database within your xampp, wamp or homestead and run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ php artisan migrate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Illuminate\Database\QueryException : SQLSTATE[42000]:&lt;/strong&gt; If you encounter the &lt;code&gt;Illuminate\Database\QueryException : SQLSTATE[42000]&lt;/code&gt; error while running the migration like in image below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A4r6s2xdY_8Pg6bvPJLmOVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A4r6s2xdY_8Pg6bvPJLmOVA.png"&gt;&lt;/a&gt;Illuminate\Database\QueryException&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;App/Providers/AppServiceProvider.php&lt;/strong&gt; and make the following updates. Within the boot method add &lt;code&gt;Schema::defaultStringLength(191);&lt;/code&gt; and add a the namespace like so &lt;code&gt;use Illuminate\Support\Facades\Schema;&lt;/code&gt;. See below 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F429%2F1%2ACRkxE3dLl6g0pgtxf9kUpA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F429%2F1%2ACRkxE3dLl6g0pgtxf9kUpA.png"&gt;&lt;/a&gt;Fix Illuminate\Database\QueryException : SQLSTATE[42000] error.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;vendor/bin/phpunit&lt;/code&gt; again and you should get a success result as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AxNAzBdtHRKL1xf1KlQOEcA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AxNAzBdtHRKL1xf1KlQOEcA.png"&gt;&lt;/a&gt;Test Result Successful!&lt;/p&gt;

&lt;p&gt;Play around a little more by adding a &lt;strong&gt;&lt;em&gt;new column&lt;/em&gt;&lt;/strong&gt; into the test, do not add to the schema migration file initially, run the test to see results, failed? Make it pass. This particular test may look boring but from the ground up you can be sure your schema integrity is accounted for.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Creating Aliases for Your CLI Commands&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that you are beginning to write tests there will be a lot of tests to run. It would make much sense to have shortcut form of some lengthy commands, the cli commands you use often. This will surely improve your productivity. &lt;a href="https://opensource.com/article/19/7/bash-aliases" rel="noopener noreferrer"&gt;&lt;strong&gt;Bash alias&lt;/strong&gt; es&lt;/a&gt; to the rescue, it is a method of supplementing or overriding &lt;strong&gt;Bash&lt;/strong&gt; commands with new ones eg allow users to customize their experience in a POSIX terminal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;alias name="command to shorten"&lt;/code&gt; &lt;strong&gt; — creates a new alias ‘name’&lt;/strong&gt; NB: there are no spaces around the &lt;code&gt;=&lt;/code&gt; sign.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;alias&lt;/code&gt; &lt;strong&gt; — displays all your set aliases&lt;/strong&gt; directly in the CLI.&lt;/li&gt;
&lt;li&gt;On a Windows PC, you may access and manage a list of your set aliases in the  &lt;strong&gt;&lt;em&gt;.bash_profile&lt;/em&gt;&lt;/strong&gt; file at &lt;code&gt;C:\Users\yourUsername\.bash\_profile&lt;/code&gt;. Here you can add, update or remove the entries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use the commands below most times in my tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;pu&lt;/em&gt;&lt;/strong&gt; &lt;code&gt;vendor/bin/phpunit&lt;/code&gt; this runs all tests within the tests directory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;puf&lt;/em&gt;&lt;/strong&gt; &lt;code&gt;vendor/bin/phpunit --filter&lt;/code&gt;  this selectively runs test within all files and test methods whose name has the string (pattern).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;putu&lt;/em&gt;&lt;/strong&gt; &lt;code&gt;vendor/bin/phpunit --testsuite Unit&lt;/code&gt; this runs all tests within the Test\Units directory only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;putf&lt;/em&gt;&lt;/strong&gt; &lt;code&gt;vendor/bin/phpunit --testsuite Feature&lt;/code&gt; this runs all tests within the &lt;code&gt;Test\Features&lt;/code&gt; directory only.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are more others but these ones comes handy for me all the time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I become paranoid if I write an app without some tests these days. I learnt the hard way and has since inculcate the habit of writing comprehensive tests for my apps &lt;em&gt;— the predictability, ease of maintenance and confidence that accompanies a well tested codebase is indescribable.&lt;/em&gt; Kindly check the remaining two parts (see links below 👇) for they are the biggest deal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⏯Part 1: &lt;strong&gt;Intro and Schema Tests&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;👉Part 2: &lt;a href="https://dev.to/tonyfrenzy/part-2-testing-model-relationships-in-laravel-basic-3a44"&gt;&lt;strong&gt;Testing Basic Model Relationships&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👉Part 3: &lt;a href="https://dev.to/tonyfrenzy/part-3-testing-model-relationships-in-laravel-polymorphic-m51"&gt;&lt;strong&gt;Testing Polymorphic Relationships&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your comments are highly appreciated.&lt;/p&gt;

</description>
      <category>phpunit</category>
      <category>laravel</category>
      <category>codequality</category>
      <category>unittesting</category>
    </item>
    <item>
      <title>SEO for Web Developers — To Use JSON-LD or Microdata?</title>
      <dc:creator>tony</dc:creator>
      <pubDate>Wed, 11 Sep 2019 19:57:24 +0000</pubDate>
      <link>https://forem.com/tonyfrenzy/seo-for-web-developers-to-use-json-ld-or-microdata-2d4p</link>
      <guid>https://forem.com/tonyfrenzy/seo-for-web-developers-to-use-json-ld-or-microdata-2d4p</guid>
      <description>&lt;h3&gt;
  
  
  — Structured Data
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AxgzznRqLjBXKsm6v1kcNaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AxgzznRqLjBXKsm6v1kcNaw.png"&gt;&lt;/a&gt;Image Source: &lt;a href="https://wordlift.io/blog/en/entity/structured-data/" rel="noopener noreferrer"&gt;&lt;strong&gt;Wordlift&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Structured Data in SEO?
&lt;/h3&gt;

&lt;p&gt;While Structured data simply refers to any data which is organized or “&lt;a href="https://moz.com/blog/structured-data-for-seo-1" rel="noopener noreferrer"&gt;given structure&lt;/a&gt;”, it can be implemented as an on-page markup that enable search engines to better understand the information available on a given web page, and then use this information to improve search results listing. It can be implemented on a website using &lt;strong&gt;Microdata, JSON-LD&lt;/strong&gt; or &lt;strong&gt;RDFa&lt;/strong&gt;  &lt;strong&gt;schema&lt;/strong&gt; types. Structured data is both &lt;strong&gt;Technical&lt;/strong&gt; and &lt;strong&gt;On-page&lt;/strong&gt;  &lt;strong&gt;SEO&lt;/strong&gt; but discussed often under Technical SEO.&lt;/p&gt;

&lt;p&gt;Structured data is an onpage SEO because it is implemented within a website unlike &lt;a href="https://www.reliablesoft.net/what-is-the-difference-between-onsite-and-offsite-seo/" rel="noopener noreferrer"&gt;&lt;strong&gt;off-page&lt;/strong&gt; (off-site) SEO&lt;/a&gt; that deals with optimizations taking place from sources external to the target website eg link building, social media &amp;amp; influencer marketing, &lt;a href="https://moz.com/learn/seo/off-site-seo" rel="noopener noreferrer"&gt;guest blogging&lt;/a&gt;, etc. On-page SEO determines how a page is displayed on web apps and on &lt;strong&gt;S&lt;/strong&gt; earch &lt;strong&gt;E&lt;/strong&gt; ngine &lt;strong&gt;R&lt;/strong&gt; esult &lt;strong&gt;P&lt;/strong&gt; age &lt;strong&gt;s&lt;/strong&gt; ( &lt;strong&gt;SERP&lt;/strong&gt; s) eg link previews, sitelink search boxes, rich card snippets, knowledge graph panels and many other enhanced snippets.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Schema is a way to label or organize your content so that search engines have a better understanding of what certain elements on your web pages are. This code provides structure to your data, which is why schema is often referred to as “structured data.” — &lt;a href="https://moz.com/beginners-guide-to-seo/technical-seo" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Moz Pro&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Search engine juggernauts such as Google, Bing, and other online search companies &lt;a href="https://searchengineland.com/schema-org-google-bing-yahoo-unite-79554" rel="noopener noreferrer"&gt;came together to standardize and develop schema markup&lt;/a&gt; in the project maintained at &lt;a href="http://www.schema.org." rel="noopener noreferrer"&gt;schema.org&lt;/a&gt;, they however have contrasting preferences. Google have preference for JSON-LD while Bing’s preferred markup type is the Microdata format (Bing now &lt;a href="https://blogs.bing.com/webmaster/august-2018/Introducing-JSON-LD-Support-in-Bing-Webmaster-Tools" rel="noopener noreferrer"&gt;support JSON-LD&lt;/a&gt;). Both technologies are quite popular and help in enhancing webpages for search engine data mining. We shall compare the pros and cons of each based on usability, portability, maintainability, etc. RDFa and Microdata are semantically similar thus the discussion about Microdata in this article also applies to RDFa (which is less popular).&lt;/p&gt;

&lt;p&gt;A related but standardized online repository of structured data for notable entities is the &lt;a href="https://wikidata.org" rel="noopener noreferrer"&gt;Wikimedia’s Wikidata.org&lt;/a&gt;. Wikidata feeds search engines with well-defined structured data about important topics.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Microdata?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Microdata&lt;/strong&gt; is a WHATWG HTML specification used to nest &lt;a href="https://en.wikipedia.org/wiki/Metadata" rel="noopener noreferrer"&gt;metadata&lt;/a&gt; &lt;em&gt;within existing content&lt;/em&gt; on web pages. &lt;a href="https://en.wikipedia.org/wiki/Search_engines" rel="noopener noreferrer"&gt;Search engines&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Web_crawlers" rel="noopener noreferrer"&gt;web crawlers&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/Web_browser" rel="noopener noreferrer"&gt;browsers&lt;/a&gt; can extract and process Microdata from a web page and use it to provide a richer browsing experience for users — &lt;a href="https://en.wikipedia.org/wiki/Microdata_(HTML)" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Microdata markup is grudgingly inline and clings tightly to HTML tags as additional attributes in the HTML markup code. See an example from &lt;a href="https://en.wikipedia.org/wiki/Microdata_(HTML)" rel="noopener noreferrer"&gt;wikipedia&lt;/a&gt; below:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Pros of Microdata✨
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Supported by all major search engines.&lt;/li&gt;
&lt;li&gt;The semantic annotations appear very close to the human-readable information.&lt;/li&gt;
&lt;li&gt;More trustable as inline semantic markup may not be providing misleading information since the values are often directly associated with actual texts on the web page.&lt;/li&gt;
&lt;li&gt;Easier to mark up pages by directly plugging in variables into the relevant sections after markup structure is set during development.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Cons of Microdata🤦
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hard to maintain&lt;/strong&gt; : &lt;a href="https://moz.com/community/q/benefits-drawbacks-to-different-schema-markup-languages-ie-json-ld-microdata-rdfa" rel="noopener noreferrer"&gt;Need lot of developer work and designer changes&lt;/a&gt;. It is hard to troubleshoot without touching the page HTML code and inline semantic markup &lt;a href="https://www.w3.org/2013/dwbp/wiki/RDF_AND_JSON-LD_UseCases#Disadvantages" rel="noopener noreferrer"&gt;can break very easily&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not Tidy&lt;/strong&gt; : Additional attributes such as &lt;em&gt;itemscope, itemtype, itemprop&lt;/em&gt; etc are known to clog up entire page as they are sandwiched within every HTML tag. This makes page structure look bloated and untidy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not as Feasible in CMS Sites&lt;/strong&gt; : To add microdata to an existing website the page HTML markup may have to be rewritten every time. CMSes (eg Wix, Wordpress) are ready-made and will present much hassle to mark up 😒.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verbose and Repetitive&lt;/strong&gt; : The additional attribute mentioned earlier does accompany every semantic declarations and contributes unnecessary repetitive texts to page structure and content.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What is JSON-LD?
&lt;/h3&gt;

&lt;p&gt;JSON-LD (JavaScript Object Notation for Linked Data) is a method of implementing &lt;a href="https://developers.google.com/structured-data/" rel="noopener noreferrer"&gt;structured data markup&lt;/a&gt; on a website. It is supported by Google, Bing, Yandex, and many smaller search engines. JSON-LD utilizes JSON notation. The Microdata markup page content above can be rewritten with JSON-LD as:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Pros of JSON-LD✨
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;The syntax is relatively simpler, easy to write and troubleshoot.&lt;/li&gt;
&lt;li&gt;The block of JSON-LD markup (semantic layer) is decoupled from the page’s HTML markup (representation layer). This separation of concerns give total flexibility and improves site maintainability.&lt;/li&gt;
&lt;li&gt;It is CMS friendly (eg Wix, Wordpress). A JSON-LD code block can be used to mark up existing web pages more easily. It entails to slotting the code into head or body section. &lt;em&gt;With Wordpress, the code can be added with plugins while on Wix, it can be pasted into the&lt;/em&gt; &lt;strong&gt;&lt;em&gt;New Tool&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;field in the settings area of a Wix account.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Like Microdata and RDFa, JSON-LD can be placed in the body of the page, but can also be used in the head.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Cons of JSON-LD🤦
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;It is more difficult for search engines to verify that the JSON-LD structured data is consistent with the actual text information on the webpage and that the JSON-LD data does not contain misleading information&lt;/li&gt;
&lt;li&gt;The block of JSON-LD does not appear alongside the human-readable information, some browsers may not easily display contextual hyperlinks in close proximity to the annotated content — &lt;a href="https://www.w3.org/2013/dwbp/wiki/RDF_AND_JSON-LD_UseCases#Disadvantages" rel="noopener noreferrer"&gt;W3.org&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Not earlier supported by Bing, this is &lt;a href="https://blogs.bing.com/webmaster/august-2018/Introducing-JSON-LD-Support-in-Bing-Webmaster-Tools" rel="noopener noreferrer"&gt;no more an issue&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Structured Data on A Dynamic Website
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Microdata On A Dynamic Website
&lt;/h4&gt;

&lt;p&gt;An example snippet of what a Microdata markup could look like on dynamic webpage. It does the job but still retains the bloated markup look, the HTML markup looks busy.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  JSON-LD On A Dynamic Website
&lt;/h4&gt;

&lt;p&gt;Gone are the days when Javascript’s DOM-rendered contents don’t work quite well with web crawlers, with the advance in technology it is &lt;a href="https://searchengineland.com/tested-googlebot-crawls-javascript-heres-learned-220157" rel="noopener noreferrer"&gt;now a no issue&lt;/a&gt;. By changing the previous example a little bit we can have data coming from a database and parsed with javascript as seen in the jsfiddle example below:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://jsfiddle.net/tonyfrenzy/d8Lc2n9s//embedded//dark" width="100%" height="600"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Viewing all the pages we mark up in this post on Google &lt;a href="https://search.google.com/structured-data/testing-tool/u/0/" rel="noopener noreferrer"&gt;Structured Data Testing Tool&lt;/a&gt;, the result will be:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F684%2F1%2AtD0edy4d_KvJ3PC4k_ojxA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F684%2F1%2AtD0edy4d_KvJ3PC4k_ojxA.png"&gt;&lt;/a&gt;Rendered result of all markup types in Google Structured Data Testing Tool .&lt;/p&gt;

&lt;p&gt;With a dynamic website the supplied data will vary based on the page being viewed. The API feeding the schema code is expected to send the appropriate variables used in generating expected markup for each individual page.&lt;/p&gt;

&lt;p&gt;There is a reason why separation of concerns is the norm in everything that has to do with a programmer’s activities. For a web developer, it starts with externalizing page assets such as stylesheets and javascript code. Even in any code writing process, you are expected to decouple your code and refactor into reusable units or methods as much as possible. The same is desirable when handling SEO schema markup to ensure code reusability and improvement of site maintainability. This separation of concern is only possible with JSON-LD.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Both Microdata and JSON-LD gets the job done and can be tested with various online testing tools and still yield exactly same result. However, JSON-LD shines. With it a website SEO maintenance is painless and ensures no interference with page HTML markup, this is a big win 💪. Chances are you are to optimize an old website or any of the third party CMS after it was originally published. Using Microdata in this scenario is next to impossible unless you restructure the HTML code base.&lt;/p&gt;

&lt;p&gt;Either of the two can be your preferred choice depending on the scenario, they both get the job done.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does these stuffs really work?
&lt;/h3&gt;

&lt;p&gt;See my &lt;strong&gt;next SEO post&lt;/strong&gt; on how I have recorded 100% &lt;strong&gt;knowledge panel&lt;/strong&gt; generation for indie music artistes using advanced combination of publicly available data to construct an artiste’s knowledge graph. The result makes it easy for Google bots to easily generate a panel for all of them.&lt;/p&gt;

</description>
      <category>structureddata</category>
      <category>seo</category>
      <category>jsonld</category>
      <category>webdeveloper</category>
    </item>
  </channel>
</rss>
