Re: [testdrivendevelopment] How would you TDD a website front-end?

"Gregory Salvan" <[email protected]> Sat, 4 Jan 2020 23:03:05 +0100
Newsgroups gmane.comp.programming.test-driven-development
Message-ID <CAAZsQLBW=YmuUcQtbzrsWzkVZ1aoMAih=jULSpRjLpM9WC57BQ@mail.gmail.com>
--000000000000f79df1059b579784
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Sorry I'm not convinced by all answers, specially when I see end to end
tests, TDD is rapid feedback and "end to end tests" are slow.
To illustrate my feelings, I've found the following article about Cohn
pyramid : https://martinfowler.com/articles/practical-test-pyramid.html
I think tests like the following for example are useless:
https://github.com/hamvocke/spring-testing/blob/master/src/test/java/examp=
le/HelloE2ERestTest.java
What's the purpose of the test shouldReturnGreeting() ? What is he testing
really ?
A different approach can consist in unit testing with small steps hello
method (String hello(@PathVariable final String lastName)), and checking i=
f
"/hello/{lastName}" is mapped to this method.
Which one gives you the fastest feedback ? In case of test break, which on=
e
will permit you to find faster where it's broken ?
Which approach document the best what you're testing ? Look at all the
tests, what if we want to show last name before first name ?
Don't you feel this kind of test are like "testing the compiler" ?

The question I try to keep in mind is **"What is my SUT"** ? In this case
spring framework is not, you can test it, but in my opinion its outside of
TDD scope.
+1 to George Dinwiddie answer

Hope it helps







Le sam. 4 janv. 2020 =C3=A0 12:57, Ken Mccormack <[email protected]> =
a
=C3=A9crit :

> You need to split functions into separate categories - orthogonal concer=
ns
> - not confuse/couple them by end to end flow tests.
>
> TBH a lot depends on the kind of quality outcomes you are looking for, t=
he
> complexity of your UI-side logic, and the tech skills of your team.
>
> My guess with Blazor is that this is just standard nunit tests running
> against C# models.  For the most part, I'd write non-200 tests here, e.g=
. a
> stubs will cover un-happy paths, malformed responses, all classes API
> errors, but also things like already created.  Other concerns would be
> tested using functional tests, probably, rather than repeat the same
> coverage in multiple places.
>
> But it depends. What is your app about?  What is its most complex piece?
> Why Blazor, rather than React?  Why silo front end tests, do you have a
> separate API team?  What are your QA processes?
>
> The typical set of application tests might be -
>
> 1. unit tests to cover  UI model logic, and in particular, to emulate
> error and fault cases
> 2. API tests - if you're in a silo, you should be throwing a set of
> consumer tests across each API release, to ensure that your basic
> assumptions aren't broken - if the api code is released independently fr=
om
> the front end (eg a microservices architecture) you need to pin down you=
r
> contract by passing the API team a set of tests to litmus check your
> expectations are being met (PACT is one approach that you might try, but
> frameworks in .net weren't very mature and tbh it's easier to roll your =
own
> approach, often)
> 3. UI automation - a journey test that hits each API once in an end to e=
nd
> flow (eg. place an order)
>
> The Cohn test pyramid is often used to describe the above - but it is al=
so
> naively misquoted and rarely deeply understood - it says *you have to te=
st
> at all (composition) levels*, and so the pyramid is a reflection of a
> typical OO composition style (i.e. not all apps will have their tests
> resemble a pyramid, many apps use functional tests, and unit test only
> negative cases.
>
> Doing more advanced CD, for example, requires some system design, i.e.
> control and observation code, or the ability to run synthetic transactio=
ns
> against production.  I'd rather do that first than unit test happy paths=
.
> In that situation a simple stub/mockist TDD approach doesn't cut it - bu=
t
> how far you go depends upon the quality outcomes you're looking to achie=
ve
> in terms of deploys per developer per day.
>
> Kennos
>
> 3, 2020 at 01:07 AM, Avi Kessner wrote:
>
> I would do it like this:
>
> User inputs a value
> Test local model updated with value.
> Form posts model to server.
> Test server handles form model and returns expected model.
> Force response to the model on the GUI
> Test the model has been updated correctly.
> Assume GUI updates correctly cause you if you used framework code to alt=
er
> the form.
> Otherwise, test your hand written html as if it was a model.
>
> On Fri, Jan 3, 2020, 03:49 Alan Baljeu via Groups.Io <alanbaljeu=3D
> [email protected]> wrote:
>
>> The pattern I have is
>>
>> User inputs a value
>> Form posts value to server
>> Server responds with new model data.
>> Form reconfigures.
>>
>> "Test changes to the model" then I think means testing the web service.
>> So don't test the view?
>>
>> Alan Baljeu
>> [email protected]
>>
>>
>>
>> On Thursday, January 2, 2020, 06:58:20 p.m. EST, Avi Kessner <
>> [email protected]> wrote:
>>
>>
>> Test the changes to the model, not the GUI itself.
>>
>> On Fri, Jan 3, 2020, 00:26 George Dinwiddie <[email protected]>
>> wrote:
>>
>> Alan,
>>
>> Way back, I played with test-driving AWT and Java Swing UIs, starting
>> with just jUnit. Given the availability of web driver libraries, you ca=
n
>> do similar things much more easily.
>>
>> In general, I tested the GUI with a test API to make sure things were
>> wired up correctly. I tested the actual API to make sure the system
>> worked correctly.
>>
>> In
>>
>> https://github.com/gdinwiddie/EquineHoroscope/tree/master/src/test/java=
/com/gdinwiddie/equinehoroscope/acceptance
>> you can see an example of re-using a test that drove the API creation t=
o
>> check the same result from the GUI by injecting a different adapter to
>> talk with the system under test.
>>
>>   - George
>>
>> > Alan Baljeu
>> > [email protected]
>> >
>> >
>>
>> --
>>   ---------------------------------------------------------------------=
-
>>    * George Dinwiddie *                      http://blog.gdinwiddie.com
>>    Software Development                    http://www.idiacomputing.com
>>    Consultant and Coach
>>   ---------------------------------------------------------------------=
-
>>
>>
>>
>>
>>
>>
>>
>>
>=20
>
>

-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#35835): https://groups.io/g/testdrivendevelopment/mess=
age/35835
Mute This Topic: https://groups.io/mt/69387056/3268755
Group Owner: [email protected]
Unsubscribe: https://groups.io/g/testdrivendevelopment/leave/6156322/74455=
6386/xyzzy  [[email protected]]
-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-


--000000000000f79df1059b579784
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Sorry I&#39;m not convinced by all answers, specially=
 when I see end to end tests, TDD is rapid feedback and &quot;end to end te=
sts&quot; are slow.<br></div><div>To illustrate my feelings, I&#39;ve found=
 the following article about Cohn pyramid : <a href=3D"https://martinfowler=
.com/articles/practical-test-pyramid.html">https://martinfowler.com/article=
s/practical-test-pyramid.html</a> <br></div><div>I think tests like the fol=
lowing for example are useless: <a href=3D"https://github.com/hamvocke/spri=
ng-testing/blob/master/src/test/java/example/HelloE2ERestTest.java">https:/=
/github.com/hamvocke/spring-testing/blob/master/src/test/java/example/Hello=
E2ERestTest.java</a></div><div></div><div>What&#39;s the purpose of the tes=
t <span class=3D"gmail-pl-en">shouldReturnGreeting</span>() ? What is he te=
sting really ?=C2=A0</div><div><span class=3D"gmail-pl-s"><span class=3D"gm=
ail-pl-pds">A different approach can consist in unit testing with small ste=
ps hello method (</span></span><span class=3D"gmail-pl-smi">String</span> <=
span class=3D"gmail-pl-en">hello</span>(<span class=3D"gmail-pl-k">@PathVar=
iable</span> <span class=3D"gmail-pl-k">final</span> <span class=3D"gmail-p=
l-smi">String</span> <span class=3D"gmail-pl-v">lastName</span>)<span class=
=
=3D"gmail-pl-s"><span class=3D"gmail-pl-pds">), and checking if  <span cla=
ss=3D"gmail-pl-s"><span class=3D"gmail-pl-pds">&quot;</span>/hello/{lastNam=
e}<span class=3D"gmail-pl-pds">&quot; is mapped to this method.<br></span><=
/span></span></span></div><div><span class=3D"gmail-pl-s"><span class=3D"gm=
ail-pl-pds"><span class=3D"gmail-pl-s"><span class=3D"gmail-pl-pds"></span>=
</span></span></span></div><div><span class=3D"gmail-pl-s"><span class=3D"g=
mail-pl-pds"></span></span></div><div><span class=3D"gmail-pl-s"><span clas=
s=3D"gmail-pl-pds">Which one gives you the fastest feedback ? In case of te=
st break, which one will permit you to find faster where it&#39;s broken ?<=
br></span></span></div><div><span class=3D"gmail-pl-s"><span class=3D"gmail=
-pl-pds">Which approach document the best what you&#39;re testing ? Look at=
 all the tests, what if we want to show last name before first name ?<br></=
span></span></div><div><span class=3D"gmail-pl-s"><span class=3D"gmail-pl-p=
ds">Don&#39;t you feel this kind of test are like &quot;testing the compile=
r&quot; ?<br></span></span></div><div><span class=3D"gmail-pl-s"><span clas=
s=3D"gmail-pl-pds"><br></span></span></div><div><span class=3D"gmail-pl-s">=
<span class=3D"gmail-pl-pds">The question I try to keep in mind is **&quot;=
What is my SUT&quot;** ? In this case spring framework is not, you can test=
 it, but in my opinion its outside of TDD scope.<br></span></span></div><di=
v><span class=3D"gmail-pl-s"><span class=3D"gmail-pl-pds">+1 to</span></spa=
n> George Dinwiddie answer<br></div><div><span class=3D"gmail-pl-s"><span c=
lass=3D"gmail-pl-pds"><br></span></span></div><div><span class=3D"gmail-pl-=
s"><span class=3D"gmail-pl-pds">Hope it helps<br></span></span></div><div><=
span class=3D"gmail-pl-s"><span class=3D"gmail-pl-pds"><br><br><br><br></sp=
an></span></div><div><span class=3D"gmail-pl-s"><span class=3D"gmail-pl-pds=
"><br><br></span></span></div></div><br><div class=3D"gmail_quote"><div dir=
=
=3D"ltr" class=3D"gmail_attr">Le=C2=A0sam. 4 janv. 2020 =C3=A0=C2=A012:57,=
 Ken Mccormack &lt;<a href=3D"mailto:[email protected]">kenmccormack@g=
mail.com</a>&gt; a =C3=A9crit=C2=A0:<br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex">You need to split functions into separate categories -=
 orthogonal concerns - not confuse/couple them by end to end flow tests.=C2=
=
=A0<br>=C2=A0<br>TBH a lot depends on the=C2=A0kind of quality outcomes yo=
u are looking for, the complexity of your UI-side logic, and the tech skill=
s of your team.<br><br>My guess with Blazor is that this is just standard n=
unit tests running against C# models.=C2=A0 For the most part, I&#39;d writ=
e non-200 tests here, e.g. a stubs will cover un-happy paths, malformed res=
ponses, all classes API errors, but also things like already created.=C2=A0=
 Other concerns would be tested using functional tests, probably, rather th=
an repeat the same coverage in multiple places.<br><br>But it depends. What=
 is your app about?=C2=A0 What is its most complex piece?=C2=A0 Why Blazor,=
 rather than React?=C2=A0 Why silo front end tests, do you have a separate =
API team?=C2=A0 What are your QA processes?<br><br>The typical set of appli=
cation tests might be -<br><br>1. unit tests to cover=C2=A0 UI model logic,=
 and in particular, to emulate error and fault cases=C2=A0<br>2. API tests =
- if you&#39;re in a silo, you should be throwing a set of consumer tests a=
cross each API release, to ensure that your basic assumptions aren&#39;t br=
oken - if the api code is released independently from the front end (eg a m=
icroservices architecture) you need to pin down your contract by passing th=
e API team a set of tests to litmus check your expectations are being met (=
PACT is one approach that you might try, but frameworks in .net weren&#39;t=
 very mature and tbh it&#39;s easier to roll your own approach, often)<br>3=
. UI automation - a journey test that hits each API once in an end to end f=
low (eg. place an order)<br><br>The Cohn test pyramid is often used to desc=
ribe the above - but it is also naively misquoted and rarely deeply underst=
ood - it says *you have to test at all (composition) levels*, and so the py=
ramid is a reflection of a typical OO composition style (i.e. not all apps =
will have their tests resemble a pyramid, many apps use functional tests, a=
nd unit test only negative cases.<br><br>Doing more advanced CD, for exampl=
e, requires some system design, i.e. control and observation code, or the a=
bility to run synthetic transactions against production.=C2=A0 I&#39;d rath=
er do that first than unit test happy paths. In that situation a simple stu=
b/mockist TDD approach doesn&#39;t cut it - but how far you go depends upon=
 the quality outcomes you&#39;re looking to achieve in terms of deploys per=
 developer per day.=C2=A0<br><br>Kennos<br><br>3, 2020 at 01:07 AM, Avi Kes=
sner wrote:<br>
<blockquote>
<div dir=3D"auto">
<div dir=3D"auto">I would do it like this:</div>
<div dir=3D"auto">=C2=A0</div>
<div>User inputs a value</div>
<div dir=3D"auto">Test local model updated with value.</div>
<div dir=3D"auto">Form posts model to server.</div>
<div dir=3D"auto">Test server handles form model and returns expected mode=
l.</div>
<div dir=3D"auto">Force response to the model on the GUI</div>
<div dir=3D"auto">Test the model has been updated correctly.</div>
<div dir=3D"auto">Assume GUI updates correctly cause you if you used frame=
work code to alter the form.</div>
<div dir=3D"auto">Otherwise, test your hand written html as if it was a mo=
del.<br><br>
<div class=3D"gmail_quote" dir=3D"auto">
<div class=3D"gmail_attr" dir=3D"ltr">On Fri, Jan 3, 2020, 03:49 Alan Balj=
eu via Groups.Io &lt;alanbaljeu=3D<a href=3D"mailto:[email protected]" ta=
rget=3D"_blank">[email protected]</a>&gt; wrote:</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border=
-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div style=3D"font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-s=
ize:16px">
<div>
<div dir=3D"ltr">The pattern I have is</div>
<div dir=3D"ltr">=C2=A0</div>
<div dir=3D"ltr">User inputs a value</div>
<div dir=3D"ltr">Form posts value to server</div>
<div dir=3D"ltr">Server responds with new model data.</div>
<div dir=3D"ltr">Form reconfigures.</div>
<div>=C2=A0</div>
<div dir=3D"ltr">&quot;Test changes to the model&quot; then I think means =
testing the web service.=C2=A0 So don&#39;t test the view?</div>
<div>=C2=A0</div>
<div>
<div style=3D"font-family:Helvetica,Arial,sans-serif;font-size:16px">
<div style=3D"color:rgb(0,0,0);font-family:Helvetica,Arial,sans-serif;font=
-size:16px">
<div>Alan Baljeu</div>
</div>
<div style=3D"color:rgb(0,0,0);font-family:Helvetica,Arial,sans-serif;font=
-size:16px"><a href=3D"mailto:[email protected]" rel=3D"noopener norefer=
rer" target=3D"_blank">[email protected]</a></div>
<div style=3D"color:rgb(0,0,0);font-family:Helvetica,Arial,sans-serif;font=
-size:16px">=C2=A0</div>
</div>
</div>
</div>
<div>=C2=A0</div>
<div>=C2=A0</div>
</div>
<div id=3D"gmail-m_2462695110694953152m_1174070532757893286ydp89e51f5yahoo=
_quoted_8399920580">
<div style=3D"font-family:&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-=
serif;font-size:13px;color:rgb(38,40,42)">
<div>On Thursday, January 2, 2020, 06:58:20 p.m. EST, Avi Kessner &lt;<a h=
ref=3D"mailto:[email protected]" rel=3D"noopener noreferrer" target=3D"_bl=
ank">[email protected]</a>&gt; wrote:</div>
<div>=C2=A0</div>
<div>=C2=A0</div>
<div>
<div id=3D"gmail-m_2462695110694953152m_1174070532757893286ydp89e51f5yiv91=
85559269">
<div>
<div>Test the changes to the model, not the GUI itself.</div>
<br clear=3D"none">
<div>
<div dir=3D"ltr">On Fri, Jan 3, 2020, 00:26 George Dinwiddie &lt;<a href=
=3D"mailto:[email protected]" rel=3D"nofollow noopener noreferrer" s=
hape=3D"rect" target=3D"_blank">[email protected]</a>&gt; wrote:</div=
>
<blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex">Alan,<br clear=3D"none"><br clear=3D"none">Way=
 back, I played with test-driving AWT and Java Swing UIs, starting <br clea=
r=3D"none">with just jUnit. Given the availability of web driver libraries,=
 you can <br clear=3D"none">do similar things much more easily.<br clear=3D=
"none"><br clear=3D"none">In general, I tested the GUI with a test API to m=
ake sure things were <br clear=3D"none">wired up correctly. I tested the ac=
tual API to make sure the system <br clear=3D"none">worked correctly.<br cl=
ear=3D"none"><br clear=3D"none">In <br clear=3D"none"><a href=3D"https://gi=
thub.com/gdinwiddie/EquineHoroscope/tree/master/src/test/java/com/gdinwiddi=
e/equinehoroscope/acceptance" rel=3D"nofollow noopener noreferrer" shape=3D=
"rect" target=3D"_blank">https://github.com/gdinwiddie/EquineHoroscope/tree=
/master/src/test/java/com/gdinwiddie/equinehoroscope/acceptance</a> <br cle=
ar=3D"none">you can see an example of re-using a test that drove the API cr=
eation to <br clear=3D"none">check the same result from the GUI by injectin=
g a different adapter to <br clear=3D"none">talk with the system under test=
.<br clear=3D"none"><br clear=3D"none">=C2=A0 - George<br clear=3D"none"><b=
r clear=3D"none">&gt; Alan Baljeu<br clear=3D"none">&gt; <a href=3D"mailto:=
[email protected]" rel=3D"nofollow noopener noreferrer" shape=3D"rect" t=
arget=3D"_blank">[email protected]</a><br clear=3D"none">&gt; <br clear=
=3D"none">&gt; <br clear=3D"none"><br clear=3D"none">-- <br clear=3D"none"=
>=C2=A0 -------------------------------------------------------------------=
---<br clear=3D"none">=C2=A0 =C2=A0* George Dinwiddie *=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <a href=3D"http://=
blog.gdinwiddie.com" rel=3D"nofollow noopener noreferrer" shape=3D"rect" ta=
rget=3D"_blank">http://blog.gdinwiddie.com</a><br clear=3D"none">=C2=A0 =C2=
=
=A0Software Development=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 <a href=3D"http://www.idiacomputing.com" rel=3D"nofol=
low noopener noreferrer" shape=3D"rect" target=3D"_blank">http://www.idiaco=
mputing.com</a><br clear=3D"none">=C2=A0 =C2=A0Consultant and Coach<br clea=
r=3D"none">=C2=A0 ---------------------------------------------------------=
-------------<br clear=3D"none"><br clear=3D"none"><br clear=3D"none"><br c=
lear=3D"none"><br clear=3D"none"></blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p>=C2=A0</p>
<p>=C2=A0</p>
</blockquote>
</div>
</div>
</div>
</blockquote>



<p></p><p></p></blockquote></div>

<div width=3D"1" style=3D"color:white;clear:both">_._,_._,_</div>
<hr>
Groups.io Links:<p>

You receive all messages sent to this group.


<p>

<a target=3D"_blank" href=3D"https://groups.io/g/testdrivendevelopment/mes=
sage/35835">View/Reply Online (#35835)</a> |


  <a target=3D"_blank" href=3D"mailto:[email protected]?subj=
ect=3DRe:%20Re%3A%20%5Btestdrivendevelopment%5D%20How%20would%20you%20TDD%2=
0a%20website%20front-end%3F">Reply To Group</a>
  
    | <a target=3D"_blank" href=3D"mailto:[email protected]?subject=3DPriva=
te:%20Re:%20Re%3A%20%5Btestdrivendevelopment%5D%20How%20would%20you%20TDD%2=
0a%20website%20front-end%3F">Reply To Sender</a>
  


|


  
    <a target=3D"_blank" href=3D"https://groups.io/mt/69387056/3268755">Mu=
te This Topic</a>
  

| <a href=3D"https://groups.io/g/testdrivendevelopment/post">New Topic</a>=
<br>



<br>

<a href=3D"https://groups.io/g/testdrivendevelopment/editsub/3268755">Your=
 Subscription</a> |
<a href=3D"mailto:[email protected]">Contact Group Own=
er</a> |

<a href=3D"https://groups.io/g/testdrivendevelopment/leave/6156322/7445563=
86/xyzzy">Unsubscribe</a>

 [[email protected]]<br>
<div width=3D"1" style=3D"color:white;clear:both">_._,_._,_</div>


--000000000000f79df1059b579784--