Video's to Watch

Fight with XCUI

On the YouTube channel: https://www.youtube.com/watch?v=Dj_mBLptzLU

When you cannot figure out a technology in your project... drop back and punt... go to example code to learn how. That is what we have done... tried to learn by doing TDD on simple example code.

TabView_Example_XCUI_Test_App on github

Nav_Example_XCUI_Test_App on github

Example that ACTUALLY work - but have commented code that DID NOT WORK.

We talk about how to use SF Symbols in Apps and test poking on one as a Tab Button.

Samantha - the best Mac voice...



<sarcasm> It is really nice that Apple tells us that the accessibility identifier is DEPRECATED - What The F....? it looks like a button... can I click and find out WHY? and what I should use moving forward?.... NO! Son Of A Bitch.

This would be a really good place for documentation - Apple!?!

XCUI - does it blend?

"Does it blend?" comes from the YouTube - Will It Blend? and the host Tom (he's from the future).

That's what I wanted to do with Xcode - press the John Conor button on the blender.

Testing with XCUI show...

What did we learn since then - that no one really knows the secrets to getting Xcode to work with the accessability identifiers that you might sprinkel into your source...

Here are two different articles - each suggesting the use of the SwiftUI element accessibilityIdentifier but with different advice/code to retreive the element inside the testing code:

1) app.staticTexts["my_ID"]

2) app.otherElements["my_ID"]

For the implementation code:

someView.accessibilityIdentifier = "my_ID"

Now one could easily test the test code to see which works...

Except for when neither instance works.... like in the SwiftUI TabView.

This is the type of situation that a company with as much money in the bank as Apple has; they could spend a bit (just a tiny portion) and hire a few technical writers to put some words in their tooling's documentation.

Last weeks
unanswered question:

Deprecation of an API. @avaliable & deprecated flag.

https://www.hackingwithswift.com/example-code/language/how-to-use-available-to-deprecate-old-apis


The Empty_Player pattern named NULL Object pattern.


Lance’s insisted on the One player, Two player, Many Players… a pattern James calls ZOMBIES

http://podcast.agileuprising.com/tdd-guided-by-zombies-with-james-grenning/


The old protocol Printable - became CustomStringConvertible protocol.

Will this help our failed test printout.

https://medium.com/@YogevSitton/use-auto-describing-objects-with-customstringconvertible-49528b55f446



Rerun the TEST shortcut. Control-Option-Command-G or Control-Option-Command-U

Under the Product > Perform Action menu.


Enable Xcode Code Coverage tooling

https://www.twitch.tv/videos/887620828

Testing clean up … in review we had some test that didn’t follow our REF ARCH idea of:

func test_methodUnderTest_secnarioDescribedDAMPly


Wonder how much code we are writing and how well we are doing with our Test?


Baseball Model 5 swift files & 5 test files with about 90 Asserts but about 700 lines of implementation code with about 700 lines of testing code.


Ol-skool method of counting lines of code:

unix> find . -name "*.swift" -print0 | xargs -0 wc -l


Mac:Model david$ find . -name "*.swift" -print0 | xargs -0 wc -l

96 ./Play.swift

437 ./Game.swift

73 ./Inning.swift

86 ./Player.swift

41 ./LineUp.swift

733 total

Mac:Model david$


Mac:Baseball-Tests david$ find . -name "*.swift" -print0 | xargs -0 wc -l

57 ./LineUpTest.swift

208 ./PlayTest.swift

237 ./GameTest.swift

33 ./PlayerTest.swift

120 ./InningTest.swift

655 total

Mac:Baseball-Tests david$


Wonder if there’s a Xcode tool that can help with this type of assessment?


A Code Coverage tool? Hmmm…


Also - a Editor > MiniMap will help with the Game.swift file that has grown so big…




What the Circular Buffer?

https://www.twitch.tv/videos/872742181?filter=highlights&sort=time


ToDo:

  • LineUp is a RingBuffer - that does NOT cycle like I want.

Here is the code we found on the net... Ring Buffer on GitHub Swift Algorithm Club. Let's rwrite our own LineUp class. It will allow the reading of the next batter to cycle around and around (thru the 9 players in the game).

Note: automatic advancement of runners on base - now the order of calls to advance runners matters.

Counting of score (Visitor vs Home)

Adding other atBat types…


Move Play method runnerOn(base, action) into Game class.

Game needs a factory method for Innings (much like Play)



Stop with the Strings Already

https://www.twitch.tv/videos/867345318?filter=highlights&sort=time


Refactoring Play init.

Recognizing the poor Play() initialization with an outcome; removed the AtBat from the init()

Which rippled thru all test….

Created a method Play.called(AtBat) // umpires call each play


Refactoring all classes to have “default” Access Level (not Public)


Pushed to GitHub


Play object is needing to keep track of the runners on base - the game situation

So the new called() method will be responsible for putting batter’s on base

Yet what moves the runners - they should move before the batter.



GREEN - do I refactor issues above?

Options:

  • 1) make Game the owner of bases and base info (NOT a Refactoring)

          • Move enums into Game (from Play)

          • Copy runnerOutcomes into Game

          • Make a nextBatter() factory for Play

          • Split RunnerOutcomes - move Bases into Game

          • Rename runnerAdvances to runnerOn(base, action)

          • runnerOutcomes - need each base line (4)

  • 2) player == method (Close to Refactoring) >> now use it!

  • 5) move EmptyPlayer to Player file

  • 9) runnerOutcomes are strings - make them RunnerAction type

  • 10) move Game-runnerActions to Play

  • 3) baseOutcomes are strings… move into Game (NOT Refactoring)

  • 4) Play needs access to Game - maybe Game is a Play Factory (NOT Refactor)

  • 12) new init() for Play that allows an AtBat for static init. - capability for real data in view.

  • 13) whichInning() whichHalf() methods

  • 14) change Inning.number : String to be named label.

  • 11) when Plays are created they should be appended to an Inning

  • 6) add another play type (new Test) - bases loaded and a WALK should Score Run.

  • 8) unit test RingBuffer (found on Net) used for lineUp in Game

      • 15) RingBuffer read didn’t wrap around on 10th read. << FIXME



In doing all of this above - I lost the static rich data of AtBat records that the running example game used on screen…. To get back that info of AtBat - added another init() method that takes the AtBat outcome of Play class. Now the display canvas & example App have data that is rich and shows the AtBat info.




Episode 9, iOS: User Stories, Reference Architecture, Test Driven Design on Game



https://www.twitch.tv/videos/855946526


- User Stories

- Code Review - some of the off line changes

- delete unused classes/files

- Enums AtBat (types of Plays) & Position (type of player)

- Maybe a bit of year end RETROSPECTIVE?? - big picture Project

- when will we be shipping something (see User Stories)

- Finish the refactoring of AtBat from inside of the Player? Is it DONE?


TDD.Academy - Dec 23 Baseball


https://www.twitch.tv/videos/852845464



Last time we refactored the AtBat string out of the Player class into the Play class.


Innings has a list of Players (was OK - but… now… needs to be a list of Plays)

Off-screen… Added Enum Positions & AtBats

We need a Game class with a list of innings; innings have a top half & bottom half which are list of plays (Play class).


OO breaking encapsulation ( Inning class has File/Default Access - not Private)


Lance’s Playground … example code - Clean Code / Primitive Obsession

“CaveMan Funk” story of marketing to primitive obsession - by Lancer Kind.

SOLID Principles - Robert (Uncle Bob)Martin


Access Control in Swift (the Open/Closed Principle in SOLID)

https://learnappmaking.com/access-control-visibility-swift-how-to/


Do we want a Game or do we use Scorecard???

Grouping mechanism ==> Game


Started with GameTest.swift for the Game.swift class.



Next Step: keep working on AtBat … it’s not in the display.

Number out of the Inning init().

Not using Scorecard …


Shippable product yet???


TDD.Academy - Dec 18


https://www.twitch.tv/videos/846428993?filter=highlights&sort=time


Remove AtBat string from Player class - moving it into Play (unused now).

ContentView is using the Player array to display it’s data.

Where to start???

Remove or Ad - which first?? We chose Ad - atBats to the Play class first.

Does Play have a property or what??

Tailor Swift intrulude…. We have a PlayTest….

In Test Cases :: expected comes first - then the ACTUAL

Did the Require of Description parameter… (this was a mistake)

XCT order of the expected vs actual does not matter... XCT is agnostic on order!

Question about ScorecardTest or PlayerTest ???

Delete the PlayerRowView.swift & test.

Want to learn TDD in a SwiftUI project? Lance Kind and I are live streaming the TDD design of an App to record and stream Baseball games. Come watch and participate in the dialogue - Twitch.TV/TDD.Academy.

Adjusting how to micro test Baseball Innings

https://www.twitch.tv/videos/835500673



Learn to make an iOS app in a durable way.

https://www.twitch.tv/videos/772602675



Learn about unit testing the Swift UI View layer with View Inspector - TDD.Accademy - Baseball (world) Series


iOS micro testing with ViewInspector, introduced by creator Alexey Naumov

https://www.twitch.tv/videos/815405793


David and Lance write a bunch of micro tests for the view layer

https://www.twitch.tv/videos/813197218


Unit Testing iOS views with "nalexn / ViewInspector"



If you are looking for a SwiftUI App tutorial - here is the very basic set of video tutorials at Ray Wenderlich - Your First iOS and SwiftUI App.

I've become a big fan of Paul Hudson (@twostraws) - Hacking with Swift - 100 days of SwiftUI is a great introduction to Paul's style of very informative concise videos.

Let's watch together...

Some of my favorite videos on Swift and good developer practices.

Great Developer Habits - WWDC 2019