Repository: Galarzaa90/tibia.py

Issue:
Parse character titles and main character information
Summer update 2019 introduced character titles, as well as a small icon that indicates which is the main character of the account in the other characters section.

Discussion:

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index a2f4d71..26d19fd 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -6,6 +6,14 @@ Changelog
     Due to this library relying on external content, older versions are not guaranteed to work.
     Try to always use the latest version.
 
+
+.. _v2.2.0:
+
+2.2.0 (2019-08-08)
+==================
+
+- Added support for account badges and character titles.
+
 .. _v2.1.0:
 
 2.1.0 (2019-06-17)
diff --git a/docs/api.rst b/docs/api.rst
index 257439d..beaf3a6 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -167,6 +167,13 @@ Auxiliary Classes
 Auxiliary classes are used to hold certain data in a standardized way, in some cases, introducing additional methods
 and properties for their use.
 
+AccountBadge
+------------------
+.. autoclass:: AccountBadge
+   :members:
+   :inherited-members:
+
+
 AccountInformation
 ------------------
 .. autoclass:: AccountInformation
diff --git a/tibiapy/__init__.py b/tibiapy/__init__.py
index 8d33782..f620b2a 100644
--- a/tibiapy/__init__.py
+++ b/tibiapy/__init__.py
@@ -13,7 +13,7 @@ from tibiapy.world import *
 from tibiapy.creature import *
 from tibiapy.client import *
 
-__version__ = '2.1.0'
+__version__ = '2.2.0'
 
 from logging import NullHandler
 
diff --git a/tibiapy/character.py b/tibiapy/character.py
index 8db5a80..7429dfe 100644
--- a/tibiapy/character.py
+++ b/tibiapy/character.py
@@ -30,7 +30,10 @@ death_reason = re.compile(r'by (?P<killers>[^.]+)(?:\.\s+Assisted by (?P<assists
 house_regexp = re.compile(r'paid until (.*)')
 guild_regexp = re.compile(r'([\s\w]+)\sof the\s(.+)')
 
+title_regexp = re.compile(r'(.*)\((\d+) titles unlocked\)')
+
 __all__ = (
+    "AccountBadge",
     "AccountInformation",
     "Achievement",
     "Character",
@@ -42,6 +45,33 @@ __all__ = (
 )
 
 
+class AccountBadge(abc.Serializable):
+    """Represents an account badge.
+
+    Attributes
+    ----------
+    name: :class:`str`
+        The name of the badge.
+    icon_url: :class:`str`
+        The URL to the badge's icon URL.
+    description: :class:`str`
+        The description of the badge.
+    """
+    __slots__ = (
+        "name",
+        "icon_url",
+        "description",
+    )
+
+    def __init__(self, name, icon_url, description):
+        self.name = name  # type: str
+        self.icon_url = icon_url  # type: str
+        self.description = description  # type: str
+
+    def __repr__(self):
+        return "<%s name=%r description=%r>" % (self.__class__.__name__, self.name, self.description)
+
+
 class AccountInformation(abc.Serializable):
     """Represents the account information of a character.
 
@@ -107,6 +137,10 @@ class Character(abc.BaseCharacter):
         The date when the character will be deleted if it is scheduled for deletion.
     former_names: :class:`list` of :class:`str`
         Previous names of the character.
+    title: :class:`str`, optional
+        The character's selected title, if any.
+    unlocked_titles: :class:`int`
+        The number of titles the character has unlocked.
     sex: :class:`Sex`
         The character's sex.
     vocation: :class:`Vocation`
@@ -135,6 +169,8 @@ class Character(abc.BaseCharacter):
         The displayed comment.
     account_status: :class:`AccountStatus`
         Whether the character's account is Premium or Free.
+    account_badges: :class:`list` of :class:`AccountBadge`
+        The displayed account badges.
     achievements: :class:`list` of :class:`Achievement`
         The achievements chosen to be displayed.
     deaths: :class:`list` of :class:`Death`
@@ -148,6 +184,8 @@ class Character(abc.BaseCharacter):
     __slots__ = (
         "former_names",
         "sex",
+        "title",
+        "unlocked_titles",
         "vocation",
         "level",
         "achievement_points",
@@ -161,6 +199,7 @@ class Character(abc.BaseCharacter):
         "account_status",
         "position",
         "comment",
+        "account_badges",
         "achievements",
         "deaths",
         "account_information",
@@ -171,6 +210,8 @@ class Character(abc.BaseCharacter):
     def __init__(self, name=None, world=None, vocation=None, level=0, sex=None, **kwargs):
         self.name = name  # type: str
         self.former_names = kwargs.get("former_names", [])  # type: List[str]
+        self.title = kwargs.get("title")  # type: Optional[str]
+        self.unlocked_titles = int(kwargs.get("unlocked_titles", 0))
         self.sex = try_enum(Sex, sex)
         self.vocation = try_enum(Vocation, vocation)
         self.level = int(level)
@@ -185,6 +226,7 @@ class Character(abc.BaseCharacter):
         self.account_status = try_enum(AccountStatus, kwargs.get("account_status"))
         self.position = kwargs.get("position")  # type: Optional[str]
         self.comment = kwargs.get("comment")  # type: Optional[str]
+        self.account_badges = kwargs.get("account_badges", [])  # type: List[AccountBadge]
         self.achievements = kwargs.get("achievements", [])  # type: List[Achievement]
         self.deaths = kwargs.get("deaths", [])  # type: List[Death]
         self.account_information = kwargs.get("account_information")  # type: Optional[AccountInformation]
@@ -253,6 +295,7 @@ class Character(abc.BaseCharacter):
         else:
             raise InvalidContent("content does not contain a tibia.com character information page.")
         char._parse_achievements(tables.get("Account Achievements", []))
+        char._parse_badges(tables.get("Account Badges", []))
         char._parse_deaths(tables.get("Character Deaths", []))
         char._parse_account_information(tables.get("Account Information", []))
         char._parse_other_characters(tables.get("Characters", []))
@@ -377,6 +420,26 @@ class Character(abc.BaseCharacter):
                 secret = True
             self.achievements.append(Achievement(name, grade, secret))
 
+    def _parse_badges(self, rows):
+        """
+        Parses the character's displayed badges
+
+        Parameters
+        ----------
+        rows: :class:`list` of :class:`bs4.Tag`
+            A list of all rows contained in the table.
+        """
+        for row in rows:
+            cols = row.find_all('td')
+            if len(cols) != 2:
+                continue
+            icon, text = cols
+            name = text.text.strip()
+            icon_image = icon.find("img")
+            description = icon_image['title']
+            icon_url = icon_image['src']
+            self.account_badges.append(AccountBadge(name, icon_url, description))
+
     def _parse_character_information(self, rows):
         """
         Parses the character's basic information and applies the found values.
@@ -428,6 +491,15 @@ class Character(abc.BaseCharacter):
         else:
             char["last_login"] = parse_tibia_datetime(char["last_login"])
 
+        m = title_regexp.match(char.get("title", ""))
+        if m:
+            name = m.group(1).strip()
+            unlocked = int(m.group(2))
+            if name == "None":
+                name = None
+            char["title"] = name
+            char["unlocked_titles"] = unlocked
+
         char["vocation"] = try_enum(Vocation, char["vocation"])
         char["sex"] = try_enum(Sex, char["sex"])
         char["account_status"] = try_enum(AccountStatus, char["account_status"])
@@ -550,7 +622,11 @@ class Character(abc.BaseCharacter):
                 continue
             name, world, status, __, __ = cols
             name = name.replace("\xa0", " ").split(". ")[1]
-            self.other_characters.append(OtherCharacter(name, world, status == "online", status == "deleted"))
+            main_img = cols_raw[0].find('img')
+            main = False
+            if main_img and main_img['title'] == "Main Character":
+                main = True
+            self.other_characters.append(OtherCharacter(name, world, status == "online", status == "deleted", main))
 
     @classmethod
     def _parse_tables(cls, parsed_content):
@@ -783,15 +859,20 @@ class OtherCharacter(abc.BaseCharacter):
         Whether the character is online or not.
     deleted: :class:`bool`
         Whether the character is scheduled for deletion or not.
+    main: :class:`bool`
+        Whether this is the main character or not.
     """
     __slots__ = (
         "world",
         "online",
-        "deleted"
+        "deleted",
+        "main",
     )
 
-    def __init__(self, name, world, online=False, deleted=False):
+    def __init__(self, name, world, online=False, deleted=False, main=False):
         self.name = name  # type: str
         self.world = world  # type: str
         self.online = online  # type: bool
         self.deleted = deleted  # type: bool
+        self.main = main  # type: bool
+
diff --git a/tibiapy/client.py b/tibiapy/client.py
index b3824a4..b25ae15 100644
--- a/tibiapy/client.py
+++ b/tibiapy/client.py
@@ -322,7 +322,7 @@ class Client:
         """Fetches the list of guilds in a world from Tibia.com
 
         Parameters
-        ---------cl-
+        ----------
         world: :class:`str`
             The name of the world.
 


Test patch:
diff --git a/tests/resources/README.md b/tests/resources/README.md
index ac20490..8096976 100644
--- a/tests/resources/README.md
+++ b/tests/resources/README.md
@@ -9,6 +9,7 @@ deaths by summons, players, assisted deaths, etcetera.
 - [tibiacom_former_names.txt](character/tibiacom_former_names.txt) - A character with former names.
 - [tibiacom_full.txt](character/tibiacom_full.txt) - A full character response.
 - [tibiacom_not_found.txt](character/tibiacom_not_found.txt) - A character not found page.
+- [tibiacom_title_badges.txt](character/tibiacom_title_badges.txt) - A character not found page.
 - [tibiadata.json](character/tibiadata.json) - A character on TibiaData, also showing Pvp deaths with assists.
 - [tibiadata_deleted.json](character/tibiadata_deleted.json) - A character scheduled for deletion on TibiaData.
 - [tibiadata_not_found.json](character/tibiadata_not_found.json) - The response of a character not found on TibiaData.
diff --git a/tests/resources/character/tibiacom_full.txt b/tests/resources/character/tibiacom_full.txt
index 39e0a3b..40890c4 100644
--- a/tests/resources/character/tibiacom_full.txt
+++ b/tests/resources/character/tibiacom_full.txt
@@ -1,50 +1,35 @@
-<div id="characters" class="Box">
-    <div class="Corner-tl" style="background-image:url(https://ssl-static-tibia.akamaized.net/images/global/content/corner-tl.gif);"></div>
-    <div class="Corner-tr" style="background-image:url(https://ssl-static-tibia.akamaized.net/images/global/content/corner-tr.gif);"></div>
-    <div class="Border_1" style="background-image:url(https://ssl-static-tibia.akamaized.net/images/global/content/border-1.gif);"></div>
-    <div class="BorderTitleText" style="background-image:url(https://ssl-static-tibia.akamaized.net/images/global/content/title-background-green.gif);"></div><img id="ContentBoxHeadline" class="Title" src="https://ssl-static-tibia.akamaized.net/images/global/strings/headline-characters.gif" alt="Contentbox headline">
-    <div class="Border_2">
-      <div class="Border_3">
-        <div class="BoxContent" style="background-image:url(https://ssl-static-tibia.akamaized.net/images/global/content/scroll.gif);">
-<table border="0" cellspacing="1" cellpadding="4" width="100%"><tbody><tr bgcolor="#505050"><td colspan="2" class="white"><b>Character Information</b></td></tr><tr bgcolor="#F1E0C6"><td width="20%">Name:</td><td>Tschas <div style="float: right"></div></td></tr><tr bgcolor="#D4C0A1"><td>Sex:</td><td>female</td></tr><tr bgcolor="#F1E0C6"><td>Vocation:</td><td>Druid</td></tr><tr bgcolor="#D4C0A1"><td>Level:</td><td>205</td></tr><tr bgcolor="#F1E0C6"><td><nobr>Achievement Points:</nobr></td><td>139</td></tr><tr bgcolor="#D4C0A1"><td>World:</td><td>Gladera</td></tr><tr bgcolor="#F1E0C6"><td>Residence:</td><td>Thais</td></tr><tr bgcolor="#D4C0A1"><td>Guild&nbsp;Membership:</td><td>Mentor of the <a href="https://www.tibia.com/community/?subtopic=guilds&amp;page=view&amp;GuildName=Redd+Alliance&amp;character=Tschas&amp;action=characters">Redd&nbsp;Alliance</a></td></tr><tr bgcolor="#F1E0C6"><td>Last Login:</td><td>Apr&nbsp;22&nbsp;2018,&nbsp;16:00:38&nbsp;CEST</td></tr><tr bgcolor="#D4C0A1"><td>Account&nbsp;Status:</td><td>Free Account</td></tr></tbody></table>
-<br><br><table border="0" cellspacing="1" cellpadding="4" width="100%"><tbody><tr bgcolor="#505050"><td colspan="2" class="white"><b>Account Achievements</b></td></tr><tr bgcolor="#F1E0C6"><td colspan="2">There are no achievements set to be displayed for this character.</td></tr></tbody></table><br><br><table border="0" cellspacing="1" cellpadding="4" width="100%"><tbody><tr bgcolor="#505050"><td colspan="2" class="white"><b>Account Information</b></td></tr><tr bgcolor="#F1E0C6"><td width="20%">Loyalty Title:</td><td>Warden of Tibia</td></tr><tr bgcolor="#D4C0A1"><td width="20%">Created:</td><td>Jan&nbsp;30&nbsp;2004,&nbsp;21:55:11&nbsp;CET</td></tr></tbody></table><br><br><table border="0" cellspacing="1" cellpadding="4" width="100%"><tbody><tr bgcolor="#505050"><td colspan="4" class="white"><b>Characters</b></td></tr><tr bgcolor="#D4C0A1"><td><b>Name</b></td><td><b>World</b></td><td><b>Status</b></td><td><b>&nbsp;</b></td></tr><tr bgcolor="#F1E0C6"><td width="20%"><nobr>1.&nbsp;Tschas</nobr></td><td width="10%"><nobr>Gladera</nobr></td><td width="70%"><img src"="https://ssl-static-tibia.akamaized.net/images/global/general/blank.gif&quot;" width="1" height="1" border="0"><br></td><td><table border="0" cellspacing="0" cellpadding="0"><form action="https://www.tibia.com/community/?subtopic=characters" method="post"></form><tbody><tr><td>
-<input type="hidden" name="name" value="Tschas">
-<input type="image" name="View Tschas" alt="View Tschas" src="https://ssl-static-tibia.akamaized.net/images/global/buttons/sbutton_view.gif" border="0" width="120" height="18">
-</td></tr></tbody></table>
-</td></tr><tr bgcolor="#D4C0A1"><td width="20%"><nobr>2.&nbsp;Tsches</nobr></td><td width="10%"><nobr>Vunira</nobr></td><td width="70%"><img src"="https://ssl-static-tibia.akamaized.net/images/global/general/blank.gif&quot;" width="1" height="1" border="0"><br></td><td><table border="0" cellspacing="0" cellpadding="0"><form action="https://www.tibia.com/community/?subtopic=characters" method="post"></form><tbody><tr><td>
-<input type="hidden" name="name" value="Tsches">
-<input type="image" name="View Tsches" alt="View Tsches" src="https://ssl-static-tibia.akamaized.net/images/global/buttons/sbutton_view.gif" border="0" width="120" height="18">
-</td></tr></tbody></table>
-</td></tr><tr bgcolor="#F1E0C6"><td width="20%"><nobr>3.&nbsp;Tschis</nobr></td><td width="10%"><nobr>Vunira</nobr></td><td width="70%"><img src"="https://ssl-static-tibia.akamaized.net/images/global/general/blank.gif&quot;" width="1" height="1" border="0"><br></td><td><table border="0" cellspacing="0" cellpadding="0"><form action="https://www.tibia.com/community/?subtopic=characters" method="post"></form><tbody><tr><td>
-<input type="hidden" name="name" value="Tschis">
-<input type="image" name="View Tschis" alt="View Tschis" src="https://ssl-static-tibia.akamaized.net/images/global/buttons/sbutton_view.gif" border="0" width="120" height="18">
-</td></tr></tbody></table>
-</td></tr><tr bgcolor="#D4C0A1"><td width="20%"><nobr>4.&nbsp;Tschiss</nobr></td><td width="10%"><nobr>Belobra</nobr></td><td width="70%"><img src"="https://ssl-static-tibia.akamaized.net/images/global/general/blank.gif&quot;" width="1" height="1" border="0"><br></td><td><table border="0" cellspacing="0" cellpadding="0"><form action="https://www.tibia.com/community/?subtopic=characters" method="post"></form><tbody><tr><td>
-<input type="hidden" name="name" value="Tschiss">
-<input type="image" name="View Tschiss" alt="View Tschiss" src="https://ssl-static-tibia.akamaized.net/images/global/buttons/sbutton_view.gif" border="0" width="120" height="18">
-</td></tr></tbody></table>
-</td></tr><tr bgcolor="#F1E0C6"><td width="20%"><nobr>5.&nbsp;Tschos</nobr></td><td width="10%"><nobr>Gladera</nobr></td><td width="70%"><img src"="https://ssl-static-tibia.akamaized.net/images/global/general/blank.gif&quot;" width="1" height="1" border="0"><br></td><td><table border="0" cellspacing="0" cellpadding="0"><form action="https://www.tibia.com/community/?subtopic=characters" method="post"></form><tbody><tr><td>
-<input type="hidden" name="name" value="Tschos">
-<input type="image" name="View Tschos" alt="View Tschos" src="https://ssl-static-tibia.akamaized.net/images/global/buttons/sbutton_view.gif" border="0" width="120" height="18">
-</td></tr></tbody></table>
-</td></tr><tr bgcolor="#D4C0A1"><td width="20%"><nobr>6.&nbsp;Tschus</nobr></td><td width="10%"><nobr>Solidera</nobr></td><td width="70%"><img src"="https://ssl-static-tibia.akamaized.net/images/global/general/blank.gif&quot;" width="1" height="1" border="0"><br></td><td><table border="0" cellspacing="0" cellpadding="0"><form action="https://www.tibia.com/community/?subtopic=characters" method="post"></form><tbody><tr><td>
-<input type="hidden" name="name" value="Tschus">
-<input type="image" name="View Tschus" alt="View Tschus" src="https://ssl-static-tibia.akamaized.net/images/global/buttons/sbutton_view.gif" border="0" width="120" height="18">
-</td></tr></tbody></table>
-</td></tr></tbody></table>
-<br><br>  <form action="https://www.tibia.com/community/?subtopic=characters" method="post">
-  <table width="100%" border="0" cellspacing="1" cellpadding="4">
-  <tbody><tr><td bgcolor="#505050" class="white"><b>Search Character</b></td></tr>
-  <tr><td bgcolor="#D4C0A1"><table border="0" cellpadding="1"><tbody><tr>
-  <td>Name:</td><td><input name="name" value="tschas" size="29" maxlength="29"></td>
-  <td><input type="image" name="Submit" src="https://ssl-static-tibia.akamaized.net/images/global/buttons/sbutton_submit.gif" border="0" width="120" height="18"></td>
-  </tr></tbody></table></td></tr>
-  </tbody></table>
-  </form>
-          </div>
-      </div>
-    </div>
-    <div class="Border_1" style="background-image:url(https://ssl-static-tibia.akamaized.net/images/global/content/border-1.gif);"></div>
-    <div class="CornerWrapper-b"><div class="Corner-bl" style="background-image:url(https://ssl-static-tibia.akamaized.net/images/global/content/corner-bl.gif);"></div></div>
-    <div class="CornerWrapper-b"><div class="Corner-br" style="background-image:url(https://ssl-static-tibia.akamaized.net/images/global/content/corner-br.gif);"></div></div>
-  </div>
\ No newline at end of file
+<div class="BoxContent" style="background-image:url(https://static.tibia.com/images/global/content/scroll.gif);">
+<table border="0" cellspacing="1" cellpadding="4" width="100%"><tr bgcolor=#505050><td colspan=2 class=white><b>Character Information</b></td></tr><tr bgcolor=#F1E0C6><td width=20%>Name:</td><td>Tschas <div style="float: right"></div></td></tr><tr bgcolor=#D4C0A1><td>Title:</td><td>None (5 titles unlocked)</td></tr><tr bgcolor=#F1E0C6><td>Sex:</td><td>female</td></tr><tr bgcolor=#D4C0A1><td>Vocation:</td><td>Druid</td></tr><tr bgcolor=#F1E0C6><td>Level:</td><td>260</td></tr><tr bgcolor=#D4C0A1><td><nobr>Achievement Points:</nobr></td><td>182</td></tr><tr bgcolor=#F1E0C6><td>World:</td><td>Gladera</td></tr><tr bgcolor=#D4C0A1><td>Residence:</td><td>Thais</td></tr><tr bgcolor=#F1E0C6><td>Guild&#160;Membership:</td><td>Gaia of the <a href="https://www.tibia.com/community/?subtopic=guilds&page=view&GuildName=Atlantis&amp;character=Tschas&amp;action=characters">Atlantis</a></td></tr><tr bgcolor=#D4C0A1><td>Last Login:</td><td>Aug&#160;04&#160;2019,&#160;13:56:59&#160;CEST</td></tr><tr bgcolor=#F1E0C6><td>Account&#160;Status:</td><td>Free Account</td></tr></table>
+<br /><br /><table border="0" cellspacing="1" cellpadding="4" width="100%"><tr bgcolor="#505050"><td colspan="2" class="white"><b>Account Achievements</b></td></tr><tr bgcolor="#F1E0C6"><td colspan="2">There are no achievements set to be displayed for this character.</td></tr></table><br /><br /><table border="0" cellspacing="1" cellpadding="4" width="100%"><tr bgcolor="#505050"><td colspan="2" class="white"><b>Account Information</b></td></tr><tr bgcolor="#F1E0C6"><td width="20%">Loyalty Title:</td><td>Squire of Tibia</td></tr><tr bgcolor="#D4C0A1"><td width="20%">Created:</td><td>Jan&#160;30&#160;2004,&#160;21:55:11&#160;CET</td></tr></table><br /><br /><TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR=#505050><TD COLSPAN=4 CLASS=white><B>Characters</B></TD></TR><TR BGCOLOR=#D4C0A1><TD><B>Name</B></TD><TD><B>World</B></TD><TD><B>Status</B></TD><TD><B>&#160;</B></TD></TR><TR BGCOLOR=#F1E0C6><TD WIDTH=20%><NOBR>1.&#160;Tschas</NOBR> <img src='https://static.tibia.com/images//account/maincharacter.png' alt='(Main Character)' title='Main Character' /></TD><TD WIDTH=10%><NOBR>Gladera</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Tschas">
+<INPUT TYPE=image NAME="View Tschas" ALT="View Tschas" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR><TR BGCOLOR=#D4C0A1><TD WIDTH=20%><NOBR>2.&#160;Tsches</NOBR></TD><TD WIDTH=10%><NOBR>Vunira</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Tsches">
+<INPUT TYPE=image NAME="View Tsches" ALT="View Tsches" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR><TR BGCOLOR=#F1E0C6><TD WIDTH=20%><NOBR>3.&#160;Tschis</NOBR></TD><TD WIDTH=10%><NOBR>Vunira</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Tschis">
+<INPUT TYPE=image NAME="View Tschis" ALT="View Tschis" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR><TR BGCOLOR=#D4C0A1><TD WIDTH=20%><NOBR>4.&#160;Tschos</NOBR></TD><TD WIDTH=10%><NOBR>Gladera</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Tschos">
+<INPUT TYPE=image NAME="View Tschos" ALT="View Tschos" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR><TR BGCOLOR=#F1E0C6><TD WIDTH=20%><NOBR>5.&#160;Tschus</NOBR></TD><TD WIDTH=10%><NOBR>Solidera</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Tschus">
+<INPUT TYPE=image NAME="View Tschus" ALT="View Tschus" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR></TABLE>
+<br /><br /> <FORM ACTION="https://www.tibia.com/community/?subtopic=characters" METHOD=post>
+<TABLE WIDTH=100% BORDER=0 CELLSPACING=1 CELLPADDING=4>
+<TR><TD BGCOLOR="#505050" CLASS=white><B>Search Character</B></TD></TR>
+<TR><TD BGCOLOR="#D4C0A1"><TABLE BORDER=0 CELLPADDING=1><TR>
+<TD>Name:</TD><TD><INPUT NAME="name" VALUE="Tschas" SIZE=29 MAXLENGTH=29></TD>
+<TD><INPUT TYPE=image NAME="Submit" SRC="https://static.tibia.com/images/global/buttons/sbutton_submit.gif" BORDER=0 WIDTH=120 HEIGHT=18></TD>
+</TR></TABLE></TD></TR>
+</TABLE>
+</FORM>
+</div>
+</div>
+</div>
diff --git a/tests/resources/character/tibiacom_title_badges.txt b/tests/resources/character/tibiacom_title_badges.txt
new file mode 100644
index 0000000..0aeb4c1
--- /dev/null
+++ b/tests/resources/character/tibiacom_title_badges.txt
@@ -0,0 +1,35 @@
+<div class="BoxContent" style="background-image:url(https://static.tibia.com/images/global/content/scroll.gif);">
+<table border="0" cellspacing="1" cellpadding="4" width="100%"><tr bgcolor=#505050><td colspan=2 class=white><b>Character Information</b></td></tr><tr bgcolor=#F1E0C6><td width=20%>Name:</td><td>Lord Feremis <div style="float: right"></div></td></tr><tr bgcolor=#D4C0A1><td>Former Names:</td><td>Lady Yanine</td></tr><tr bgcolor=#F1E0C6><td>Title:</td><td>None (6 titles unlocked)</td></tr><tr bgcolor=#D4C0A1><td>Sex:</td><td>male</td></tr><tr bgcolor=#F1E0C6><td>Vocation:</td><td>Elder Druid</td></tr><tr bgcolor=#D4C0A1><td>Level:</td><td>212</td></tr><tr bgcolor=#F1E0C6><td><nobr>Achievement Points:</nobr></td><td>140</td></tr><tr bgcolor=#D4C0A1><td>World:</td><td>Gladera</td></tr><tr bgcolor=#F1E0C6><td>Residence:</td><td>Roshamuul</td></tr><tr bgcolor=#D4C0A1><td>House:</td><td> <a href="https://www.tibia.com/community/?subtopic=houses&amp;page=view&amp;world=Gladera&amp;town=Ankrahmun&amp;houseid=59041&amp;character=Lord+Feremis&amp;action=characters">Unklath I b</a> (Ankrahmun) is paid until Aug&#160;15&#160;2019</td></tr><tr bgcolor=#F1E0C6><td>Guild&#160;Membership:</td><td>Amigo Mexicano of the <a href="https://www.tibia.com/community/?subtopic=guilds&page=view&GuildName=Club+de+amigos&amp;character=Lord+Feremis&amp;action=characters">Club&#160;de&#160;amigos</a></td></tr><tr bgcolor=#D4C0A1><td>Last Login:</td><td>Aug&#160;06&#160;2019,&#160;01:34:07&#160;CEST</td></tr><tr bgcolor=#F1E0C6><td>Account&#160;Status:</td><td>Premium Account</td></tr></table>
+<br /><br /><table border="0" cellspacing="1" cellpadding="4" width="100%"><tr bgcolor="#505050"><td colspan="2" class="white"><b>Account Badges</b></td></tr><tr bgcolor="#F1E0C6"><td width='64'><img src='https://static.tibia.com/images//badges/badge_accountage4.png' alt='Ancient Hero' title='Your account is older than 15 years' /></td><td>Ancient Hero</td></tr><tr bgcolor="#D4C0A1"><td width='64'><img src='https://static.tibia.com/images//badges/badge_accountage3.png' alt='Senior Hero' title='Your account is older than 10 years.' /></td><td>Senior Hero</td></tr><tr bgcolor="#F1E0C6"><td width='64'><img src='https://static.tibia.com/images//badges/badge_accountage2.png' alt='Veteran Hero' title='Your account is older than 5 years.' /></td><td>Veteran Hero</td></tr><tr bgcolor="#D4C0A1"><td width='64'><img src='https://static.tibia.com/images//badges/badge_accountage1.png' alt='Fledgeling Hero' title='Your account is older than 1 year.' /></td><td>Fledgeling Hero</td></tr><tr bgcolor="#F1E0C6"><td width='64'><img src='https://static.tibia.com/images//badges/badge_tibialoyalist1.png' alt='Tibia Loyalist (Grade 1)' title='You earned more than 100 loyalty points.' /></td><td>Tibia Loyalist (Grade 1)</td></tr></table><br /><br /><table border="0" cellspacing="1" cellpadding="4" width="100%"><tr bgcolor="#505050"><td colspan="2" class="white"><b>Account Achievements</b></td></tr><tr bgcolor="#F1E0C6"><td><img style="width:18px;height:18px;margin-right:2px;" src="https://static.tibia.com/images/global/general/achievement-grade-symbol.gif" alt="Tibia Achievement" /></td><td width="80%">Number of the Beast</td></tr><tr bgcolor="#D4C0A1"><td><img style="width:18px;height:18px;margin-right:2px;" src="https://static.tibia.com/images/global/general/achievement-grade-symbol.gif" alt="Tibia Achievement" /></td><td width="80%">Rockstar<img style="position:absolute;width:44px;height:20px;margin-left:12px;margin-top:-2px;right:35px" src="https://static.tibia.com/images/global/general/achievement-secret-symbol.gif" alt="Tibia Secret Achievement" /></td></tr><tr bgcolor="#F1E0C6"><td><img style="width:18px;height:18px;margin-right:2px;" src="https://static.tibia.com/images/global/general/achievement-grade-symbol.gif" alt="Tibia Achievement" /></td><td width="80%">Safely Stored Away<img style="position:absolute;width:44px;height:20px;margin-left:12px;margin-top:-2px;right:35px" src="https://static.tibia.com/images/global/general/achievement-secret-symbol.gif" alt="Tibia Secret Achievement" /></td></tr><tr bgcolor="#D4C0A1"><td><img style="width:18px;height:18px;margin-right:2px;" src="https://static.tibia.com/images/global/general/achievement-grade-symbol.gif" alt="Tibia Achievement" /><img style="width:18px;height:18px;margin-right:2px;" src="https://static.tibia.com/images/global/general/achievement-grade-symbol.gif" alt="Tibia Achievement" /></td><td width="80%">Turncoat<img style="position:absolute;width:44px;height:20px;margin-left:12px;margin-top:-2px;right:35px" src="https://static.tibia.com/images/global/general/achievement-secret-symbol.gif" alt="Tibia Secret Achievement" /></td></tr><tr bgcolor="#F1E0C6"><td><img style="width:18px;height:18px;margin-right:2px;" src="https://static.tibia.com/images/global/general/achievement-grade-symbol.gif" alt="Tibia Achievement" /></td><td width="80%">Vanity<img style="position:absolute;width:44px;height:20px;margin-left:12px;margin-top:-2px;right:35px" src="https://static.tibia.com/images/global/general/achievement-secret-symbol.gif" alt="Tibia Secret Achievement" /></td></tr></table><br /><br /><table border="0" cellspacing="1" cellpadding="4" width="100%"><tr bgcolor="#505050"><td colspan="2" class="white"><b>Character Deaths</b></td></tr><tr bgcolor="#F1E0C6"><td width="25%" valign="top">Jul&#160;31&#160;2019,&#160;21:55:40&#160;CEST</td><td>Died at Level 206 by a grim reaper.</td></tr><tr bgcolor="#D4C0A1"><td width="25%" valign="top">Jul&#160;27&#160;2019,&#160;01:30:26&#160;CEST</td><td>Died at Level 203 by a gazer spectre.</td></tr><tr bgcolor="#F1E0C6"><td width="25%" valign="top">Jul&#160;21&#160;2019,&#160;02:12:12&#160;CEST</td><td>Died at Level 190 by a skeleton elite warrior.</td></tr><tr bgcolor="#D4C0A1"><td width="25%" valign="top">Jul&#160;16&#160;2019,&#160;06:48:23&#160;CEST</td><td>Died at Level 183 by a frazzlemaw.</td></tr></table><br /><br /><table border="0" cellspacing="1" cellpadding="4" width="100%"><tr bgcolor="#505050"><td colspan="2" class="white"><b>Account Information</b></td></tr><tr bgcolor="#F1E0C6"><td width="20%">Loyalty Title:</td><td>Warden of Tibia</td></tr><tr bgcolor="#D4C0A1"><td width="20%">Created:</td><td>Jun&#160;19&#160;2003,&#160;05:26:35&#160;CEST</td></tr></table><br /><br /><TABLE BORDER=0 CELLSPACING=1 CELLPADDING=4 WIDTH=100%><TR BGCOLOR=#505050><TD COLSPAN=4 CLASS=white><B>Characters</B></TD></TR><TR BGCOLOR=#D4C0A1><TD><B>Name</B></TD><TD><B>World</B></TD><TD><B>Status</B></TD><TD><B>&#160#160;</B></TD></TR><TR BGCOLOR=#F1E0C6><TD WIDTH=20%><NOBR>1.&#160;Chicharron&#160;De&#160;Cachete</NOBR></TD><TD WIDTH=10%><NOBR>Gladera</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Chicharron De Cachete">
+<INPUT TYPE=image NAME="View Chicharron De Cachete" ALT="View Chicharron De Cachete" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR><TR BGCOLOR=#D4C0A1><TD WIDTH=20%><NOBR>2.&#160;Iztli</NOBR></TD><TD WIDTH=10%><NOBR>Gladera</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Iztli">
+<INPUT TYPE=image NAME="View Iztli" ALT="View Iztli" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR><TR BGCOLOR=#F1E0C6><TD WIDTH=20%><NOBR>3.&#160;Lord&#160;Feremis</NOBR> <img src='https://static.tibia.com/images//account/maincharacter.png' alt='(Main Character)' title='Main Character' /></TD><TD WIDTH=10%><NOBR>Gladera</NOBR></TD><TD WIDTH=70%><B CLASS=green>online</B></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Lord Feremis">
+<INPUT TYPE=image NAME="View Lord Feremis" ALT="View Lord Feremis" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR><TR BGCOLOR=#D4C0A1><TD WIDTH=20%><NOBR>4.&#160;Oxy&#160;Dado</NOBR></TD><TD WIDTH=10%><NOBR>Kenora</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Oxy Dado">
+<INPUT TYPE=image NAME="View Oxy Dado" ALT="View Oxy Dado" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR><TR BGCOLOR=#F1E0C6><TD WIDTH=20%><NOBR>5.&#160;Tamnpic&#160;Hugo</NOBR></TD><TD WIDTH=10%><NOBR>Lobera</NOBR></TD><TD WIDTH=70%><IMG SRC"=https://static.tibia.com/images/global/general/blank.gif" WIDTH=1 HEIGHT=1 BORDER=0><BR></TD><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><FORM ACTION=https://www.tibia.com/community/?subtopic=characters METHOD=post><TR><TD>
+<INPUT TYPE=hidden NAME=name VALUE="Tamnpic Hugo">
+<INPUT TYPE=image NAME="View Tamnpic Hugo" ALT="View Tamnpic Hugo" SRC="https://static.tibia.com/images/global/buttons/sbutton_view.gif" BORDER=0 WIDTH=120 HEIGHT=18>
+</TD></TR></FORM></TABLE>
+</TD></TR></TABLE>
+<br /><br /> <FORM ACTION="https://www.tibia.com/community/?subtopic=characters" METHOD=post>
+<TABLE WIDTH=100% BORDER=0 CELLSPACING=1 CELLPADDING=4>
+<TR><TD BGCOLOR="#505050" CLASS=white><B>Search Character</B></TD></TR>
+<TR><TD BGCOLOR="#D4C0A1"><TABLE BORDER=0 CELLPADDING=1><TR>
+<TD>Name:</TD><TD><INPUT NAME="name" VALUE="Lord Feremis" SIZE=29 MAXLENGTH=29></TD>
+<TD><INPUT TYPE=image NAME="Submit" SRC="https://static.tibia.com/images/global/buttons/sbutton_submit.gif" BORDER=0 WIDTH=120 HEIGHT=18></TD>
+</TR></TABLE></TD></TR>
+</TABLE>
+</FORM>
+</div>
+</div>
+</div>
diff --git a/tests/tests_character.py b/tests/tests_character.py
index 22ddc71..3f84798 100644
--- a/tests/tests_character.py
+++ b/tests/tests_character.py
@@ -3,7 +3,7 @@ import unittest
 
 import tests.tests_guild
 from tests.tests_tibiapy import TestCommons
-from tibiapy import Character, CharacterHouse, Death, InvalidContent, Killer
+from tibiapy import Character, CharacterHouse, Death, InvalidContent, Killer, AccountBadge
 from tibiapy.enums import AccountStatus, Sex, Vocation
 from tibiapy.utils import parse_tibia_datetime
 
@@ -13,6 +13,7 @@ FILE_CHARACTER_FORMER_NAMES = "character/tibiacom_former_names.txt"
 FILE_CHARACTER_SPECIAL_POSITION = "character/tibiacom_special_position.txt"
 FILE_CHARACTER_DELETION = "character/tibiacom_deletion.txt"
 FILE_CHARACTER_DEATHS_COMPLEX = "character/tibiacom_deaths_complex.txt"
+FILE_CHARACTER_TITLE_BADGES = "character/tibiacom_title_badges.txt"
 
 FILE_CHARACTER_TIBIADATA = "character/tibiadata.json"
 FILE_CHARACTER_TIBIADATA_UNHIDDEN = "character/tibiadata_unhidden.json"
@@ -31,31 +32,36 @@ class TestCharacter(TestCommons, unittest.TestCase):
         self.assertEqual(mock_character.sex, character.sex)
 
     # region Tibia.com Character Tests
-    def testCharacter(self):
+    def test_character_from_content(self):
+        """Testing parsing a character's HTML content"""
         character = Character.from_content(self._load_resource(FILE_CHARACTER_RESOURCE))
-        self._compare_character(Character("Tschas", "Gladera", Vocation.DRUID, 205, Sex.FEMALE), character)
+        self._compare_character(Character("Tschas", "Gladera", Vocation.DRUID, 260, Sex.FEMALE), character)
         self.assertIsNotNone(character.guild_membership)
-        self.assertEqual("Redd Alliance", character.guild_membership.name)
-        self.assertEqual("Mentor", character.guild_membership.rank)
+        self.assertEqual("Atlantis", character.guild_membership.name)
+        self.assertEqual("Gaia", character.guild_membership.rank)
         self.assertIsNotNone(character.guild_url)
         self.assertIsNone(character.married_to_url)
         self.assertEqual(character.guild_name, character.guild_membership.name)
         self.assertEqual(character.guild_rank, character.guild_membership.rank)
         self.assertEqual(AccountStatus.FREE_ACCOUNT, character.account_status)
-        self.assertEqual(139, character.achievement_points)
+        self.assertEqual(182, character.achievement_points)
         self.assertIsNone(character.house)
         self.assertIsNone(character.deletion_date)
         self.assertIsNotNone(character.deaths)
         self.assertEqual(0, character.deaths.__len__())
-        self.assertEqual(parse_tibia_datetime("Apr 22 2018, 16:00:38 CEST"), character.last_login)
+        self.assertEqual(parse_tibia_datetime("Aug 04 2019, 13:56:59 CEST"), character.last_login)
         self.assertEqual(character.url, Character.get_url(character.name))
+        self.assertEqual(5, len(character.other_characters))
+        self.assertFalse(character.hidden)
 
-    def testCharacterNotFound(self):
+    def test_character_from_content_not_found(self):
+        """Testing parsing a character not found page"""
         content = self._load_resource(FILE_CHARACTER_NOT_FOUND)
         char = Character.from_content(content)
         self.assertIsNone(char)
 
-    def testCharacterFormerNames(self):
+    def test_character_from_content_with_former_names(self):
+        """Testing parsing a character that has former names"""
         content = self._load_resource(FILE_CHARACTER_FORMER_NAMES)
         char = Character.from_content(content)
         self.assertIsInstance(char.former_names, list)
@@ -68,14 +74,16 @@ class TestCharacter(TestCommons, unittest.TestCase):
         self.assertEqual(char.house.world, char.world)
         self.assertIsInstance(char.house.paid_until_date, datetime.date)
 
-    def testCharacterPosition(self):
+    def test_character_from_content_with_position(self):
+        """Testing parsing a character with a position"""
         content = self._load_resource(FILE_CHARACTER_SPECIAL_POSITION)
         char = Character.from_content(content)
         self.assertEqual(char.name, "Steve")
         self.assertEqual(char.position, "CipSoft Member")
         self.assertEqual(char.account_information.position, "CipSoft Member")
 
-    def testCharacterDeletion(self):
+    def test_character_from_content_deleted_character(self):
+        """Testing parsing a character scheduled for deletion"""
         content = self._load_resource(FILE_CHARACTER_DELETION)
         char = Character.from_content(content)
         self.assertEqual("Expendable Dummy", char.name)
@@ -83,7 +91,8 @@ class TestCharacter(TestCommons, unittest.TestCase):
         self.assertIsInstance(char.deletion_date, datetime.datetime)
         self.assertEqual(parse_tibia_datetime("Oct 08 2018 22:17:00 CEST"), char.deletion_date)
 
-    def testCharacterComplexDeaths(self):
+    def test_character_from_content_complex_deaths(self):
+        """Testing parsing a character with complex deaths (summons, assists, etc)"""
         content = self._load_resource(FILE_CHARACTER_DEATHS_COMPLEX)
         char = Character.from_content(content)
         self.assertTrue(char.deaths)
@@ -92,14 +101,32 @@ class TestCharacter(TestCommons, unittest.TestCase):
         oldest_death = char.deaths[-1]
         self.assertEqual(oldest_death.killer.summon, "a fire elemental")
 
-    def testCharacterUnrelated(self):
+    def test_character_from_content_badges_and_title(self):
+        """Testing parsing a character with account badges and a title"""
+        content = self._load_resource(FILE_CHARACTER_TITLE_BADGES)
+        char = Character.from_content(content)
+        self.assertEqual("Lord Feremis", char.name)
+        self.assertEqual(140, char.achievement_points)
+        self.assertIsNone(char.title)
+        self.assertEqual(6, char.unlocked_titles)
+        self.assertEqual(5, len(char.account_badges))
+        self.assertEqual(1, len(char.former_names))
+        for badge in char.account_badges:
+            self.assertIsInstance(badge, AccountBadge)
+            self.assertIsInstance(badge.name, str)
+            self.assertIsInstance(badge.icon_url, str)
+            self.assertIsInstance(badge.description, str)
+
+    def test_character_from_content_unrelated(self):
+        """Testing parsing an unrelated tibia.com section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             Character.from_content(content)
 
     # endregion
 
-    def testDeathTypes(self):
+    def test_death_types(self):
+        """Testing different death types"""
         assisted_suicide = Death("Galarzaa", 280, killers=[Killer("Galarzaa", True), Killer("a pixy")],
                                  time=datetime.datetime.now())
         self.assertEqual(assisted_suicide.killer, assisted_suicide.killers[0])
@@ -111,8 +138,9 @@ class TestCharacter(TestCommons, unittest.TestCase):
         self.assertTrue(spawn_invasion.by_player)
 
     # region TibiaData Character tests
-        
-    def testCharacterTibiaData(self):
+
+    def test_character_from_tibiadata(self):
+        """Testing parsing TibiaData content"""
         content = self._load_resource(FILE_CHARACTER_TIBIADATA)
         char = Character.from_tibiadata(content)
 
@@ -129,7 +157,8 @@ class TestCharacter(TestCommons, unittest.TestCase):
 
         self.assertTrue(char.deaths[3].by_player)
 
-    def testCharacterTibiaDataUnhidden(self):
+    def test_character_from_tibiadata_unhidden(self):
+        """Testing parsing an unhidden character"""
         content = self._load_resource(FILE_CHARACTER_TIBIADATA_UNHIDDEN)
         char = Character.from_tibiadata(content)
 
@@ -143,7 +172,8 @@ class TestCharacter(TestCommons, unittest.TestCase):
         self.assertEqual(char.house.world, char.world)
         self.assertIsInstance(char.house.paid_until_date, datetime.date)
 
-    def testCharacterTibiaDataDeleted(self):
+    def test_character_from_tibiadata_deleted(self):
+        """Testing parsing a deleted character"""
         content = self._load_resource(FILE_CHARACTER_TIBIADATA_DELETED)
         char = Character.from_tibiadata(content)
 
@@ -154,14 +184,16 @@ class TestCharacter(TestCommons, unittest.TestCase):
         self.assertIsNone(char.guild_name)
         self.assertIsNone(char.last_login)
 
-    def testCharacterTibiaDataPosition(self):
+    def test_character_from_tibiadata_position(self):
+        """Testing parsing a character with position"""
         content = self._load_resource(FILE_CHARACTER_TIBIADATA_SPECIAL_POSITION)
         char = Character.from_tibiadata(content)
         self.assertEqual(char.name, "Steve")
         self.assertEqual(char.position, "CipSoft Member")
         self.assertEqual(char.account_information.position, "CipSoft Member")
 
-    def testCharacterSummonDeaths(self):
+    def test_character_from_tibiadata_summon_deaths(self):
+        """Testing parsing a character with summon deaths"""
         content = self._load_resource(FILE_CHARACTER_TIBIADATA_DEATHS_SUMMON)
         char = Character.from_tibiadata(content)
         self.assertTrue(char.deaths)
@@ -170,15 +202,18 @@ class TestCharacter(TestCommons, unittest.TestCase):
         self.assertTrue(summon_death.killers[2].summon, "a fire elemental")
         self.assertTrue(summon_death.killers[2].name, "Hasi Pupsi")
 
-    def testCharacterTibiaDataNotFound(self):
+    def test_character_from_tibiadata_not_found(self):
+        """Testing parsing a not found character"""
         content = self._load_resource(FILE_CHARACTER_TIBIADATA_NOT_FOUND)
         char = Character.from_tibiadata(content)
         self.assertIsNone(char)
 
-    def testCharacterTibiaDataInvalidJson(self):
+    def test_character_from_tibiadata_invalid_json(self):
+        """Testing parsing an invalid JSON string"""
         with self.assertRaises(InvalidContent):
             Character.from_tibiadata("<html><b>Not a json string</b></html>")
 
-    def testCharacterTibiaDataUnrelatedJson(self):
+    def test_character_from_tibiadata_unrelated_json(self):
+        """Testing parsing an unrelated TibiaData section"""
         with self.assertRaises(InvalidContent):
             Character.from_tibiadata(self._load_resource(tests.tests_guild.FILE_GUILD_TIBIADATA))
diff --git a/tests/tests_client.py b/tests/tests_client.py
index 21b3091..eeca685 100644
--- a/tests/tests_client.py
+++ b/tests/tests_client.py
@@ -3,7 +3,6 @@ import datetime
 import aiohttp
 import asynctest
 from aioresponses import aioresponses
-from tests.tests_world import FILE_WORLD_FULL, FILE_WORLD_LIST
 
 from tests.tests_character import FILE_CHARACTER_RESOURCE, FILE_CHARACTER_NOT_FOUND
 from tests.tests_guild import FILE_GUILD_FULL, FILE_GUILD_LIST
@@ -12,6 +11,7 @@ from tests.tests_house import FILE_HOUSE_FULL, FILE_HOUSE_LIST
 from tests.tests_kill_statistics import FILE_KILL_STATISTICS_FULL
 from tests.tests_news import FILE_NEWS_LIST, FILE_NEWS_ARTICLE
 from tests.tests_tibiapy import TestCommons
+from tests.tests_world import FILE_WORLD_FULL, FILE_WORLD_LIST
 from tibiapy import Client, Character, Guild, Highscores, VocationFilter, Category, House, ListedHouse, ListedGuild, \
     KillStatistics, ListedNews, News, World, WorldOverview, Forbidden, NetworkError, BoostedCreature
 
@@ -23,7 +23,8 @@ class TestClient(asynctest.TestCase, TestCommons):
     async def tearDown(self):
         await self.client.session.close()
 
-    async def testPassSession(self):
+    async def test_client_init_pass_session(self):
+        """Testing creating an instance passing a session"""
         headers = {"User-Agent": "Python Unit Test"}
         session = aiohttp.ClientSession(headers=headers)
         client = Client(session=session)
@@ -33,7 +34,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         await client.session.close()
 
     @aioresponses()
-    async def testRequestErrors(self, mock):
+    async def test_client_handle_errors(self, mock):
+        """Testing error handling"""
         mock.get(WorldOverview.get_url(), status=403)
         with self.assertRaises(Forbidden):
             await self.client.fetch_world_list()
@@ -51,7 +53,8 @@ class TestClient(asynctest.TestCase, TestCommons):
             await self.client.fetch_recent_news(30)
 
     @aioresponses()
-    async def testFetchCharacter(self, mock):
+    async def test_client_fetch_character(self, mock):
+        """Testing fetching a character"""
         name = "Tschas"
         content = self._load_resource(FILE_CHARACTER_RESOURCE)
         mock.get(Character.get_url(name), status=200, body=content)
@@ -60,7 +63,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(character, Character)
 
     @aioresponses()
-    async def testFetchCharacterNotFound(self, mock):
+    async def test_client_fetch_character_not_found(self, mock):
+        """Testing fetching a non existent character"""
         name = "Nezune"
         content = self._load_resource(FILE_CHARACTER_NOT_FOUND)
         mock.get(Character.get_url(name), status=200, body=content)
@@ -69,7 +73,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsNone(character)
 
     @aioresponses()
-    async def testFetchGuild(self, mock):
+    async def test_client_fetch_guild(self, mock):
+        """Testing fetching a guild"""
         name = "Vitam et Mortem"
         content = self._load_resource(FILE_GUILD_FULL)
         mock.get(Guild.get_url(name), status=200, body=content)
@@ -78,7 +83,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(guild, Guild)
 
     @aioresponses()
-    async def testFetchGuildList(self, mock):
+    async def test_client_fetch_world_guilds(self, mock):
+        """Testing fetching a world's guild list"""
         world = "Zuna"
         content = self._load_resource(FILE_GUILD_LIST)
         mock.get(ListedGuild.get_world_list_url(world), status=200, body=content)
@@ -87,7 +93,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(guilds[0], ListedGuild)
 
     @aioresponses()
-    async def testFetchHighscores(self, mock):
+    async def test_client_fetch_highscores_page(self, mock):
+        """Testing fetching a highscores page"""
         world = "Estela"
         category = Category.MAGIC_LEVEL
         vocations = VocationFilter.KNIGHTS
@@ -98,7 +105,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(highscores, Highscores)
 
     @aioresponses()
-    async def testFetchHouse(self, mock):
+    async def test_client_fetch_house(self, mock):
+        """Testing fetching a house"""
         world = "Antica"
         house_id = 5236
         content = self._load_resource(FILE_HOUSE_FULL)
@@ -108,7 +116,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(house, House)
 
     @aioresponses()
-    async def testFetchHouseList(self, mock):
+    async def test_client_fetch_world_houses(self, mock):
+        """Testing fetching a world's houses"""
         world = "Antica"
         city = "Edron"
         content = self._load_resource(FILE_HOUSE_LIST)
@@ -119,7 +128,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(houses[0], ListedHouse)
 
     @aioresponses()
-    async def testFetchKillStatistics(self, mock):
+    async def test_client_fetch_kill_statistics(self, mock):
+        """Testing fetching kill statistics"""
         world = "Antica"
         content = self._load_resource(FILE_KILL_STATISTICS_FULL)
         mock.get(KillStatistics.get_url(world), status=200, body=content)
@@ -128,7 +138,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(kill_statistics, KillStatistics)
 
     @aioresponses()
-    async def testFetchRecentNews(self, mock):
+    async def test_client_fetch_recent_news(self, mock):
+        """Testing fetching recent nows"""
         content = self._load_resource(FILE_NEWS_LIST)
         mock.post(ListedNews.get_list_url(), status=200, body=content)
         recent_news = await self.client.fetch_recent_news(30)
@@ -136,14 +147,16 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(recent_news, list)
         self.assertIsInstance(recent_news[0], ListedNews)
 
-    async def testFetchNewsInvalidDates(self):
+    async def test_client_fetch_news_archive_invalid_dates(self):
+        """Testing fetching news archive with invalid dates"""
         today = datetime.date.today()
         yesterday = today - datetime.timedelta(days=1)
         with self.assertRaises(ValueError):
             await self.client.fetch_news_archive(today, yesterday)
 
     @aioresponses()
-    async def testFetchNews(self, mock):
+    async def test_client_fetch_news(self, mock):
+        """Testing fetch news"""
         news_id = 6000
         content = self._load_resource(FILE_NEWS_ARTICLE)
         mock.get(News.get_url(news_id), status=200, body=content)
@@ -152,7 +165,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(news, News)
 
     @aioresponses()
-    async def testFetchWorld(self, mock):
+    async def test_client_fetch_world(self, mock):
+        """Testing fetching a world"""
         name = "Antica"
         content = self._load_resource(FILE_WORLD_FULL)
         mock.get(World.get_url(name), status=200, body=content)
@@ -161,7 +175,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(world, World)
 
     @aioresponses()
-    async def testFetchWorldList(self, mock):
+    async def test_client_fetch_world_list(self, mock):
+        """Testing fetching the world list"""
         content = self._load_resource(FILE_WORLD_LIST)
         mock.get(WorldOverview.get_url(), status=200, body=content)
         worlds = await self.client.fetch_world_list()
@@ -169,7 +184,8 @@ class TestClient(asynctest.TestCase, TestCommons):
         self.assertIsInstance(worlds, WorldOverview)
 
     @aioresponses()
-    async def testFetchBoostedCreature(self, mock):
+    async def test_client_fetch_boosted_creature(self, mock):
+        """Testing fetching the boosted creature"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         mock.get(News.get_list_url(), status=200, body=content)
         creature = await self.client.fetch_boosted_creature()
diff --git a/tests/tests_creature.py b/tests/tests_creature.py
index e9f439c..2921aec 100644
--- a/tests/tests_creature.py
+++ b/tests/tests_creature.py
@@ -6,14 +6,16 @@ from tibiapy import BoostedCreature, InvalidContent
 
 class TestCreature(TestCommons, unittest.TestCase):
     # region Tibia.com Tests
-    def testBoostedCreature(self):
+    def test_creature_from_content(self):
+        """Testing parsing a boosted creature"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         creature = BoostedCreature.from_content(content)
 
         self.assertIsInstance(creature, BoostedCreature)
         self.assertEqual("Skeleton Warrior", creature.name)
 
-    def testBoostedCreatureNotTibiaCom(self):
+    def test_creature_from_content_not_tibiacom(self):
+        """Testing parsing a page that is not Tibia.com"""
         with self.assertRaises(InvalidContent):
             BoostedCreature.from_content("<html><div><p>Nothing</p></div></html>")
 
diff --git a/tests/tests_guild.py b/tests/tests_guild.py
index 9cfd3cd..b66ed0c 100644
--- a/tests/tests_guild.py
+++ b/tests/tests_guild.py
@@ -26,7 +26,8 @@ class TestsGuild(TestCommons, unittest.TestCase):
     def setUp(self):
         self.guild = Guild()
 
-    def testGuildFull(self):
+    def test_guild_from_content(self):
+        """Testing parsing a guild"""
         content = self._load_resource(FILE_GUILD_FULL)
         guild = Guild.from_content(content)
         self.assertIsInstance(guild, Guild, "Guild should be a Guild object.")
@@ -55,17 +56,20 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertEqual(guild.guildhall.world, guild.world)
         self.assertIsInstance(guild.guildhall.paid_until_date, datetime.date)
 
-    def testGuildNotFound(self):
+    def test_guild_from_content_not_found(self):
+        """Testing parsing a non existent guild"""
         content = self._load_resource(FILE_GUILD_NOT_FOUND)
         guild = Guild.from_content(content)
         self.assertIsNone(guild)
 
-    def testGuildUnrelated(self):
+    def test_guild_from_content_unrelated(self):
+        """Testing parsing an unrelated tibiacom section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             Guild.from_content(content)
 
-    def testGuildInfoComplete(self):
+    def test_guild_from_content_complete_info(self):
+        """Testing parsing a guild with all information possible"""
         content = self._load_parsed_resource(FILE_GUILD_INFO_COMPLETE)
         self.guild._parse_guild_disband_info(content)
         self.assertIsNone(self.guild.disband_condition, "Guild should not be under disband warning")
@@ -89,7 +93,8 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertEqual(datetime.date(2015, 7, 23), self.guild.founded)
         self.assertTrue(self.guild.active, "Guild should be active")
 
-    def testGuildInfoMinimum(self):
+    def test_guild_from_content_minimum_info(self):
+        """Testing parsing a guild with the minimum information possible"""
         content = self._load_parsed_resource(FILE_GUILD_INFO_MINIMUM)
         self.guild._parse_guild_disband_info(content)
         self.assertIsNone(self.guild.disband_condition, "Guild should not be under disband warning")
@@ -106,7 +111,8 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertEqual("Gladera", self.guild.world)
         self.assertEqual(datetime.date(year=2018, month=5, day=18), self.guild.founded)
 
-    def testGuildInfoDisbanding(self):
+    def test_guild_from_content_disbanding(self):
+        """Testing parsing a guild that is disbanding"""
         content = self._load_parsed_resource(FILE_GUILD_INFO_DISBANDING)
         self.guild._parse_guild_info(content)
         self.assertTrue(self.guild.active, "Guild should be active")
@@ -115,7 +121,8 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertIsNotNone(self.guild.disband_condition, "Guild should have a disband warning")
         self.assertEqual(self.guild.disband_date, datetime.date(2018, 8, 17), "Guild should have disband date")
 
-    def testGuildInfoFormation(self):
+    def test_guild_from_content_formation(self):
+        """Testing parsing a guild that is in formation"""
         content = self._load_parsed_resource(FILE_GUILD_INFO_FORMATION)
         Guild._parse_guild_info(self.guild, content)
         self.assertFalse(self.guild["active"], "Guild should not be active")
@@ -124,7 +131,8 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertIsNotNone(self.guild.disband_condition, "Guild should have a disband warning")
         self.assertEqual(self.guild.disband_date, datetime.date(2018, 8, 16), "Guild should have disband date")
 
-    def testGuildList(self):
+    def test_listed_guild_from_content(self):
+        """Testing parsing the list of guilds of a world"""
         content = self._load_resource(FILE_GUILD_LIST)
         guilds = ListedGuild.list_from_content(content)
         self.assertTrue(guilds)
@@ -133,17 +141,20 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertTrue(guilds[0].active)
         self.assertFalse(guilds[-1].active)
 
-    def testGuildListNotFound(self):
+    def test_listed_guild_from_content_not_found(self):
+        """Testing parsing the guild list of a world that doesn't exist"""
         content = self._load_resource(FILE_GUILD_LIST_NOT_FOUND)
         guilds = ListedGuild.list_from_content(content)
         self.assertIsNone(guilds)
 
-    def testGuildListUnrelated(self):
+    def test_listed_guild_from_content_unrelated(self):
+        """Testing parsing and unrelated section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             ListedGuild.list_from_content(content)
 
-    def testInvitationDate(self):
+    def test_parse_invited_member_date(self):
+        """Testing the invitation date of a invited member"""
         name = "Tschas"
         date = "Invitation Date"
         values = name, date
@@ -151,7 +162,8 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertIsNotNone(self.guild.invites)
         self.assertListEqual(self.guild.invites, [])
 
-    def testInvitedMember(self):
+    def test_parse_invited_member(self):
+        """Testing parsing an invited member"""
         name = "Tschas"
         date = "Jun 20 2018"
         values = name, date
@@ -161,28 +173,32 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertEqual(self.guild.invites[0].name, name)
         self.assertEqual(self.guild.invites[0].date, datetime.date(2018, 6, 20))
 
-    def testMemberJoinDate(self):
+    def test_guild_member_init_join_date(self):
+        """Testing different combinations of join dates for instance creation"""
         self.assertIsInstance(GuildMember(joined="Jul 20 2018").joined, datetime.date)
         self.assertIsInstance(GuildMember(joined=datetime.date.today()).joined, datetime.date)
         self.assertIsInstance(GuildMember(joined=datetime.datetime.now()).joined, datetime.date)
         self.assertIsNone(GuildMember(joined=None).joined)
         self.assertIsNone(GuildMember(joined="Jul 20").joined)
 
-    def testInviteDate(self):
+    def test_guild_invite_init_invite_date(self):
+        """Testing different combinations of invite dates for instance creation"""
         self.assertIsInstance(GuildInvite(date="Jul 20 2018").date, datetime.date)
         self.assertIsInstance(GuildInvite(date=datetime.date.today()).date, datetime.date)
         self.assertIsInstance(GuildInvite(date=datetime.datetime.now()).date, datetime.date)
         self.assertIsNone(GuildInvite(date=None).date)
         self.assertIsNone(GuildInvite(date="Jul 20").date)
 
-    def testGuildFounded(self):
+    def test_guild_init_founded(self):
+        """Testing different founded date inputs for instance creation"""
         self.assertIsInstance(Guild(founded="Jul 20 2018").founded, datetime.date)
         self.assertIsInstance(Guild(founded=datetime.date.today()).founded, datetime.date)
         self.assertIsInstance(Guild(founded=datetime.datetime.now()).founded, datetime.date)
         self.assertIsNone(Guild(founded=None).founded)
         self.assertIsNone(Guild(founded="Jul 20").founded)
 
-    def testGuildTibiaData(self):
+    def test_guild_from_tibiadata(self):
+        """Testing parsing a guild from TibiaData"""
         content = self._load_resource(FILE_GUILD_TIBIADATA)
         guild = Guild.from_tibiadata(content)
 
@@ -194,33 +210,39 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertEqual(guild.guildhall.world, guild.world)
         self.assertIsNotNone(guild.logo_url)
 
-    def testGuildTibiaDataNotFound(self):
+    def test_guild_from_tibiadata_not_found(self):
+        """Testing parsing a non existent guild"""
         content = self._load_resource(FILE_GUILD_TIBIADATA_NOT_FOUND)
         guild = Guild.from_tibiadata(content)
         self.assertIsNone(guild)
 
-    def testGuildTibiaDataDisbanding(self):
+    def test_guild_from_tibiadata_disbanding(self):
+        """Testing parsing a disbanding guild from TibiaData"""
         content = self._load_resource(FILE_GUILD_TIBIADATA_DISBANDING)
         guild = Guild.from_tibiadata(content)
         self.assertIsNotNone(guild.disband_condition)
         self.assertEqual(guild.disband_date, datetime.date(2018, 12, 26))
 
-    def testGuildTibiaDataInvited(self):
+    def test_guild_from_tibiadata_with_invites(self):
+        """Testing parsing a guild with invites"""
         content = self._load_resource(FILE_GUILD_TIBIADATA_INVITED)
         guild = Guild.from_tibiadata(content)
         self.assertTrue(len(guild.invites) > 0)
         self.assertIsInstance(guild.invites[0], GuildInvite)
 
-    def testGuildTibiaDataInvalid(self):
+    def test_guild_from_tibiadata_invalid_json(self):
+        """Testing parsing an invalid json"""
         with self.assertRaises(InvalidContent):
             Guild.from_tibiadata("<html><p>definitely not a json string</p></html>")
 
-    def testGuildTibiaDataUnrelated(self):
+    def test_guild_from_tibiadata_unrelated_section(self):
+        """Testing parsing a different TibiaData json"""
         content = self._load_resource(tests.tests_character.FILE_CHARACTER_TIBIADATA)
         with self.assertRaises(InvalidContent):
             Guild.from_tibiadata(content)
 
-    def testGuildListTibiaData(self):
+    def test_listed_guild_from_tibiadata(self):
+        """Testing parsing a guild list from TibiaData"""
         content = self._load_resource(FILE_GUILD_TIBIADATA_LIST)
         guilds = ListedGuild.list_from_tibiadata(content)
         self.assertTrue(guilds)
@@ -230,17 +252,20 @@ class TestsGuild(TestCommons, unittest.TestCase):
         self.assertTrue(guilds[0].active)
         self.assertFalse(guilds[-1].active)
 
-    def testGuildListTibiaDataNotFound(self):
+    def test_listed_guild_from_tibiadata_not_found(self):
+        """Testing parsing a non existent guild"""
         content = self._load_resource(FILE_GUILD_TIBIADATA_LIST_NOT_FOUND)
         guilds = ListedGuild.list_from_tibiadata(content)
         # There's no way to tell if the searched world doesn't exist or has no guilds
         self.assertEqual(guilds, [])
 
-    def testGuildListTibiaDataUnrelated(self):
+    def test_listed_guild_from_tibiadata_unrelated_section(self):
+        """Testing parsing an unrelated section"""
         content = self._load_resource(tests.tests_character.FILE_CHARACTER_TIBIADATA)
         with self.assertRaises(InvalidContent):
             ListedGuild.list_from_tibiadata(content)
 
-    def testGuildListTibiaDataInvalidJson(self):
+    def test_listed_guild_from_tibiadata_invalid_json(self):
+        """Testing parsing an invalid json"""
         with self.assertRaises(InvalidContent):
             ListedGuild.list_from_tibiadata("<b>Not JSON</b>")
diff --git a/tests/tests_highscores.py b/tests/tests_highscores.py
index 66ecab4..16b3599 100644
--- a/tests/tests_highscores.py
+++ b/tests/tests_highscores.py
@@ -18,7 +18,8 @@ FILE_HIGHSCORES_TIBIADATA_EMPTY = "highscores/tibiadata_empty.json"
 
 class TestHighscores(unittest.TestCase, TestCommons):
     # region Tibia.com Tests
-    def testHighscores(self):
+    def test_highscores_from_content(self):
+        """Testing parsing Highscores"""
         content = self._load_resource(FILE_HIGHSCORES_FULL)
         highscores = Highscores.from_content(content)
 
@@ -39,7 +40,8 @@ class TestHighscores(unittest.TestCase, TestCommons):
             self.assertIsInstance(entry.rank, int)
             self.assertIsInstance(entry.value, int)
 
-    def testHighscoresExperience(self):
+    def test_highscores_from_content_highscores(self):
+        """Testing parsing experience highscores"""
         content = self._load_resource(FILE_HIGHSCORES_EXPERIENCE)
         highscores = Highscores.from_content(content)
 
@@ -57,7 +59,8 @@ class TestHighscores(unittest.TestCase, TestCommons):
             self.assertIsInstance(entry.value, int)
             self.assertIsInstance(entry.level, int)
 
-    def testHighscoresLoyalty(self):
+    def test_highscores_from_content_loyalty(self):
+        """Testing parsing experience loyalty"""
         content = self._load_resource(FILE_HIGHSCORES_LOYALTY)
         highscores = Highscores.from_content(content)
 
@@ -75,13 +78,15 @@ class TestHighscores(unittest.TestCase, TestCommons):
             self.assertIsInstance(entry.value, int)
             self.assertIsInstance(entry.title, str)
 
-    def testHighscoresEmpty(self):
+    def test_highscores_from_content_empty(self):
+        """Testing parsing highscores empty highscores"""
         content = self._load_resource(FILE_HIGHSCORES_EMPTY)
         highscores = Highscores.from_content(content)
 
         self.assertIsNone(highscores)
 
-    def testHighscoresUnrelated(self):
+    def test_highscores_from_content_unrelated_section(self):
+        """Testing parsing an unrelated section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             Highscores.from_content(content)
@@ -89,7 +94,8 @@ class TestHighscores(unittest.TestCase, TestCommons):
     # endregion
 
     # region TibiaData.com Tests
-    def testHighscoresTibiaData(self):
+    def test_highscores_from_tibiadata(self):
+        """Testing parsing highscores from TibiaData"""
         content = self._load_resource(FILE_HIGHSCORES_TIBIADATA_FULL)
         highscores = Highscores.from_tibiadata(content)
 
@@ -108,7 +114,8 @@ class TestHighscores(unittest.TestCase, TestCommons):
             self.assertIsInstance(entry.rank, int)
             self.assertIsInstance(entry.value, int)
 
-    def testHighscoresTibiaDataExperience(self):
+    def test_highscores_from_tibiadata_experience(self):
+        """Testing parsing experience highscores"""
         content = self._load_resource(FILE_HIGHSCORES_TIBIADATA_EXPERIENCE)
         highscores = Highscores.from_tibiadata(content)
 
@@ -125,7 +132,8 @@ class TestHighscores(unittest.TestCase, TestCommons):
             self.assertIsInstance(entry.value, int)
             self.assertIsInstance(entry.level, int)
 
-    def testHighscoresTibiaDataLoyalty(self):
+    def test_highscores_from_tibiadata_loyalty(self):
+        """Testing parsing loyalty highscores"""
         content = self._load_resource(FILE_HIGHSCORES_TIBIADATA_LOYALTY)
         highscores = Highscores.from_tibiadata(content)
 
@@ -142,13 +150,15 @@ class TestHighscores(unittest.TestCase, TestCommons):
             self.assertIsInstance(entry.value, int)
             self.assertIsInstance(entry.title, str)
 
-    def testHighscoresTibaDataEmpty(self):
+    def test_highscores_from_tibiadata_empty(self):
+        """Testing parsing empty highscores"""
         content = self._load_resource(FILE_HIGHSCORES_TIBIADATA_EMPTY)
         highscores = Highscores.from_tibiadata(content)
 
         self.assertIsNone(highscores)
 
-    def testHighscoresTibiaDataListUnrelated(self):
+    def test_highscores_from_tibiadata_unrelated_section(self):
+        """Testing parsing an unrelated section"""
         with self.assertRaises(InvalidContent):
             Highscores.from_tibiadata(self._load_resource(tests.tests_character.FILE_CHARACTER_TIBIADATA))
 
diff --git a/tests/tests_house.py b/tests/tests_house.py
index 10ace46..3dcf770 100644
--- a/tests/tests_house.py
+++ b/tests/tests_house.py
@@ -27,7 +27,8 @@ class TestsHouse(TestCommons, unittest.TestCase):
     def setUp(self):
         self.guild = {}
 
-    def testHouse(self):
+    def test_house_from_content(self):
+        """Testing parsing a house"""
         content = self._load_resource(FILE_HOUSE_FULL)
         house = House.from_content(content)
 
@@ -48,7 +49,8 @@ class TestsHouse(TestCommons, unittest.TestCase):
         house_json = json.loads(house_json_raw)
         self.assertEqual(house.image_url, house_json["image_url"])
 
-    def testHouseStatusTransferred(self):
+    def test_house_from_content_transferred(self):
+        """Testing parsing a house being transferred"""
         house = House("Name")
         content = self._load_resource(FILE_HOUSE_STATUS_TRANSFER)
         house._parse_status(content)
@@ -59,7 +61,8 @@ class TestsHouse(TestCommons, unittest.TestCase):
         self.assertTrue(house.transfer_accepted)
         self.assertEqual(house.transfer_price, 850000)
 
-    def testHouseStatusRented(self):
+    def test_house_parse_status_rented(self):
+        """Testing parsing a rented status"""
         house = House("Name")
         content = self._load_resource(FILE_HOUSE_STATUS_RENTED)
         house._parse_status(content)
@@ -67,7 +70,8 @@ class TestsHouse(TestCommons, unittest.TestCase):
         self.assertEqual(house.owner, "Thorcen")
         self.assertIsInstance(house.paid_until, datetime.datetime)
 
-    def testHouseStatusWithBids(self):
+    def test_house_parse_status_with_bids(self):
+        """Testing parsing a house status with bids"""
         house = House("Name")
         content = self._load_resource(FILE_HOUSE_STATUS_WITH_BIDS)
         house._parse_status(content)
@@ -77,25 +81,29 @@ class TestsHouse(TestCommons, unittest.TestCase):
         self.assertEqual(house.highest_bidder, "King of Bosnia")
         self.assertIsInstance(house.auction_end, datetime.datetime)
 
-    def testHouseStatusWithoutBids(self):
+    def test_house_parse_status_without_bids(self):
+        """Testing parsing the status of a house with no bids"""
         house = House("Name")
         content = self._load_resource(FILE_HOUSE_STATUS_NO_BIDS)
         house._parse_status(content)
         self.assertEqual(house.status, HouseStatus.AUCTIONED)
         self.assertIsNone(house.auction_end)
 
-    def testHouseNotFound(self):
+    def test_house_from_content_not_found(self):
+        """Testing parsing a house that doesn't exist"""
         content = self._load_resource(FILE_HOUSE_NOT_FOUND)
         house = House.from_content(content)
 
         self.assertIsNone(house)
 
-    def testHouseUnrelated(self):
+    def test_house_from_content_unrelated(self):
+        """Testing parsing an unrelated section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             House.from_content(content)
 
-    def testHouseList(self):
+    def test_listed_house_from_content(self):
+        """Testing parsing the house list of a world and city"""
         content = self._load_resource(FILE_HOUSE_LIST)
         houses = ListedHouse.list_from_content(content)
 
@@ -110,24 +118,28 @@ class TestsHouse(TestCommons, unittest.TestCase):
 
         self.assertEqual(houses[25].status, HouseStatus.RENTED)
 
-    def testHouseListEmpty(self):
+    def test_listed_house_from_content_empty(self):
+        """Testing parsing an empty house list"""
         content = self._load_resource(FILE_HOUSE_LIST_EMPTY)
         houses = ListedHouse.list_from_content(content)
 
         self.assertEqual(len(houses), 0)
 
-    def testHouseListNotFound(self):
+    def test_listed_house_from_content_not_found(self):
+        """Testing parsing an empty house list"""
         content = self._load_resource(FILE_HOUSE_NOT_FOUND)
         houses = ListedHouse.list_from_content(content)
 
         self.assertIsNone(houses)
 
-    def testHouseListUnrelated(self):
+    def test_listed_house_from_content_unrelated(self):
+        """Testing parsing an unrelated section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             ListedHouse.list_from_content(content)
 
-    def testHouseTibiaData(self):
+    def test_house_from_tibiadata(self):
+        """Testing parsing a house from TibiaData"""
         content = self._load_resource(FILE_HOUSE_TIBIADATA)
         house = House.from_tibiadata(content)
 
@@ -139,22 +151,26 @@ class TestsHouse(TestCommons, unittest.TestCase):
         self.assertEqual(house.status, HouseStatus.AUCTIONED)
         self.assertIsNone(house.owner)
 
-    def testHouseTibiaDataNotFound(self):
+    def test_house_from_tibiadata_not_found(self):
+        """Testing parsing a house that doesn't exist"""
         content = self._load_resource(FILE_HOUSE_TIBIADATA_NOT_FOUND)
         house = House.from_tibiadata(content)
 
         self.assertIsNone(house)
 
-    def testHouseTibiaDataInvalid(self):
+    def test_house_from_tibiadata_invalid_json(self):
+        """Testing parsing an invalid json"""
         with self.assertRaises(InvalidContent):
             House.from_tibiadata("<p>Not json</p>")
 
-    def testGuildTibiaDataUnrelated(self):
+    def test_house_from_tibiadata_unrelated(self):
+        """Testing parsing an unrelated section"""
         content = self._load_resource(tests.tests_character.FILE_CHARACTER_TIBIADATA)
         with self.assertRaises(InvalidContent):
             House.from_tibiadata(content)
 
-    def testHouseTibiaDataList(self):
+    def test_listed_house_list_from_tibiadata(self):
+        """Testing parsing a house list from TibiaData"""
         content = self._load_resource(FILE_HOUSE_TIBIADATA_LIST)
         houses = ListedHouse.list_from_tibiadata(content)
 
@@ -167,17 +183,20 @@ class TestsHouse(TestCommons, unittest.TestCase):
         self.assertIsInstance(houses[0].id, int)
         self.assertIsNotNone(ListedHouse.get_list_url_tibiadata(houses[0].world, houses[0].town))
 
-    def testHouseTibiaDataListNotFound(self):
+    def test_listed_house_list_from_tibiadata_not_found(self):
+        """Testing parsing a list of a world that doesn't exist"""
         content = self._load_resource(FILE_HOUSE_TIBIADATA_LIST_NOT_FOUND)
         houses = ListedHouse.list_from_tibiadata(content)
 
         self.assertIsInstance(houses, list)
         self.assertEqual(len(houses), 0)
 
-    def testHouseTibiaDataListInvalidJson(self):
+    def test_listed_house_list_from_tibiadata_invalid_json(self):
+        """Testing parsing an invalid json"""
         with self.assertRaises(InvalidContent):
             ListedHouse.list_from_tibiadata("nope")
 
-    def testHouseTibiaDataListUnrelated(self):
+    def test_listed_house_list_from_tibiadata_unrelated_section(self):
+        """Testing parsing an unrelated section"""
         with self.assertRaises(InvalidContent):
             ListedHouse.list_from_tibiadata(self._load_resource(tests.tests_character.FILE_CHARACTER_TIBIADATA))
diff --git a/tests/tests_kill_statistics.py b/tests/tests_kill_statistics.py
index 266f7c2..33eb4d8 100644
--- a/tests/tests_kill_statistics.py
+++ b/tests/tests_kill_statistics.py
@@ -9,7 +9,8 @@ FILE_KILL_STATISTICS_EMPTY = "kill_statistics/tibiacom_empty.txt"
 
 class TestHighscores(TestCommons, unittest.TestCase):
     # region Tibia.com Tests
-    def testKillStatistics(self):
+    def test_kill_statistics_from_content(self):
+        """Testing parsing kill statistics"""
         content = self._load_resource(FILE_KILL_STATISTICS_FULL)
         kill_statistics = KillStatistics.from_content(content)
 
@@ -25,13 +26,15 @@ class TestHighscores(TestCommons, unittest.TestCase):
         self.assertEqual(kill_statistics.players.last_week_killed, 7)
         self.assertEqual(kill_statistics.players.last_week_killed, kill_statistics.players.last_week_players_killed)
 
-    def testKillStatisticsEmpty(self):
+    def test_kill_statistics_from_content_empty(self):
+        """Testing parsing empty kill statistics"""
         content = self._load_resource(FILE_KILL_STATISTICS_EMPTY)
         kill_statistics = KillStatistics.from_content(content)
 
         self.assertIsNone(kill_statistics)
 
-    def testKillStatisticsUnrelated(self):
+    def test_kill_statistics_from_content_unrelated_section(self):
+        """Testing parsing an unrelated section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             KillStatistics.from_content(content)
diff --git a/tests/tests_news.py b/tests/tests_news.py
index 89b72da..0edd53e 100644
--- a/tests/tests_news.py
+++ b/tests/tests_news.py
@@ -14,7 +14,8 @@ FILE_NEWS_TICKER = "news/tibiacom_news_ticker.txt"
 
 class TestNews(TestCommons, unittest.TestCase):
     # region Tibia.com Tests
-    def testNewsList(self):
+    def test_listed_news_from_content(self):
+        """Testing parsing news"""
         content = self._load_resource(FILE_NEWS_LIST)
         news_list = ListedNews.list_from_content(content)
         self.assertGreater(len(news_list), 0)
@@ -28,27 +29,32 @@ class TestNews(TestCommons, unittest.TestCase):
         self.assertIsNotNone(latest_news.url)
         self.assertEqual(latest_news.url, ListedNews.get_url(latest_news.id))
 
-    def testNewsListEmpty(self):
+    def test_listed_news_from_content_empty(self):
+        """Testing parsing a news article that doesn't exist"""
         content = self._load_resource(FILE_NEWS_LIST_EMPTY)
         news_list = ListedNews.list_from_content(content)
         self.assertEqual(len(news_list), 0)
 
-    def testNewsListUnrelated(self):
+    def test_listed_news_from_content_unrelated(self):
+        """Testing parsing an unrelated section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             ListedNews.list_from_content(content)
 
-    def testNewsEmpty(self):
+    def test_news_from_content_empty(self):
+        """Testing parsing an empty news article"""
         content = self._load_resource(FILE_NEWS_EMPTY)
         news = News.from_content(content)
         self.assertIsNone(news)
 
-    def testNewsUnrelated(self):
+    def test_news_from_content_unrelated(self):
+        """Testing parsing an unrelated section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             News.from_content(content)
 
-    def testNewsTicker(self):
+    def test_news_from_content_ticker(self):
+        """Testing parsing a news ticker"""
         content = self._load_resource(FILE_NEWS_TICKER)
         news = News.from_content(content)
 
@@ -58,7 +64,8 @@ class TestNews(TestCommons, unittest.TestCase):
         self.assertEqual(news.title, "News Ticker")
         self.assertIsNone(news.thread_id)
 
-    def testNewsArticle(self):
+    def test_news_from_content_article(self):
+        """Testing parsing an article"""
         content = self._load_resource(FILE_NEWS_ARTICLE)
         news = News.from_content(content)
 
diff --git a/tests/tests_utils.py b/tests/tests_utils.py
index 780ddf6..249d026 100644
--- a/tests/tests_utils.py
+++ b/tests/tests_utils.py
@@ -2,7 +2,6 @@ import datetime
 import unittest
 
 import tibiapy
-
 from tests.tests_tibiapy import TestCommons
 from tibiapy import enums, utils
 from tibiapy.utils import parse_integer, parse_tibia_money
@@ -35,7 +34,8 @@ TIBIADATA_DATE = "2018-12-20"
 
 
 class TestUtils(TestCommons, unittest.TestCase):
-    def testSerializableGetItem(self):
+    def test_serializable_get_item(self):
+        """Testing the muliple ways to use __get__ for Serializable"""
         # Class inherits from Serializable
         world = tibiapy.World("Calmera")
 
@@ -57,7 +57,7 @@ class TestUtils(TestCommons, unittest.TestCase):
         with self.assertRaises(KeyError):
             world["custom"] = "custom value"
 
-    def testTibiaDateTime(self):
+    def test_parse_tibia_datetime(self):
         time = utils.parse_tibia_datetime(TIBIA_DATETIME_CEST)
         self.assertIsInstance(time, datetime.datetime)
         self.assertEqual(time.month, 7)
@@ -76,33 +76,33 @@ class TestUtils(TestCommons, unittest.TestCase):
         self.assertEqual(time.minute, 13)
         self.assertEqual(time.second, 32)
 
-    def testTibiaDateInvalidTimezone(self):
+    def test_parse_tibia_datetime_invalid_timezone(self):
         time = utils.parse_tibia_datetime(TIBIA_DATETIME_PST)
         self.assertIsNone(time)
 
-    def testTibiaDateTimeInvalid(self):
+    def test_parse_tibia_datetime_invalid_datetime(self):
         time = utils.parse_tibia_datetime(TIBIA_DATETIME_INVALID)
         self.assertIsNone(time)
 
-    def testTibiaDate(self):
+    def test_parse_tibia_date(self):
         date = utils.parse_tibia_date(TIBIA_DATE)
         self.assertIsInstance(date, datetime.date)
         self.assertEqual(date.month, 6)
         self.assertEqual(date.day, 20)
         self.assertEqual(date.year, 2018)
 
-    def testTibiaFullDate(self):
+    def test_parse_tibia_date_full(self):
         date = utils.parse_tibia_full_date(TIBIA_FULL_DATE)
         self.assertIsInstance(date, datetime.date)
         self.assertEqual(date.month, 7)
         self.assertEqual(date.day, 23)
         self.assertEqual(date.year, 2015)
 
-    def testTibiaDateInvalid(self):
+    def test_parse_tibia_date_invalid(self):
         date = utils.parse_tibia_date(TIBIA_DATETIME_INVALID)
         self.assertIsNone(date)
 
-    def testTibiaDataDatetime(self):
+    def test_parse_tibia_datetime_from_datetime(self):
         date = utils.parse_tibiadata_datetime(TIBIADATA_DATETIME_CET)
         self.assertIsInstance(date, datetime.datetime)
 
@@ -117,7 +117,7 @@ class TestUtils(TestCommons, unittest.TestCase):
         date = utils.parse_tibiadata_datetime(TIBIA_DATE)
         self.assertIsNone(date)
 
-    def testTryDate(self):
+    def test_try_date(self):
         date = utils.try_date(datetime.datetime.now())
         self.assertIsInstance(date, datetime.date)
 
@@ -134,7 +134,7 @@ class TestUtils(TestCommons, unittest.TestCase):
         date = utils.try_date(TIBIADATA_DATE)
         self.assertIsInstance(date, datetime.date)
 
-    def testTryDateTime(self):
+    def test_try_date_time(self):
         date_time = utils.try_datetime(datetime.datetime.now())
         self.assertIsInstance(date_time, datetime.datetime)
 
@@ -144,7 +144,7 @@ class TestUtils(TestCommons, unittest.TestCase):
         date_time = utils.try_datetime(TIBIADATA_DATETIME_CET)
         self.assertIsInstance(date_time, datetime.datetime)
 
-    def testParseNumberWords(self):
+    def test_parse_number_words(self):
         self.assertEqual(utils.parse_number_words("one"), 1)
         self.assertEqual(utils.parse_number_words("no"), 0)
         self.assertEqual(utils.parse_number_words("..."), 0)
@@ -152,18 +152,18 @@ class TestUtils(TestCommons, unittest.TestCase):
         self.assertEqual(utils.parse_number_words("one hundred two"), 102)
         self.assertEqual(utils.parse_number_words("two thousand forty five"), 2045)
 
-    def testTryEnum(self):
+    def test_try_enum(self):
         self.assertEqual(utils.try_enum(enums.Sex, "male"), enums.Sex.MALE)
         self.assertEqual(utils.try_enum(enums.TransferType, "", enums.TransferType.REGULAR), enums.TransferType.REGULAR)
         self.assertEqual(utils.try_enum(enums.WorldLocation, enums.WorldLocation.EUROPE), enums.WorldLocation.EUROPE)
 
-    def testEnumStr(self):
+    def test_enum_str(self):
         self.assertEqual(str(enums.Sex.MALE), enums.Sex.MALE.value)
         self.assertEqual(enums.VocationFilter.from_name("royal paladin"), enums.VocationFilter.PALADINS)
         self.assertEqual(enums.VocationFilter.from_name("unknown"), enums.VocationFilter.ALL)
         self.assertIsNone(enums.VocationFilter.from_name("unknown", False))
 
-    def testParseTibiaMoney(self):
+    def test_parse_tibia_money(self):
         self.assertEqual(1000, parse_tibia_money("1k"))
         self.assertEqual(5000000, parse_tibia_money("5kk"))
         self.assertEqual(2500, parse_tibia_money("2.5k"))
@@ -171,7 +171,7 @@ class TestUtils(TestCommons, unittest.TestCase):
         with self.assertRaises(ValueError):
             parse_tibia_money("abc")
 
-    def testParseInteger(self):
+    def test_parse_integer(self):
         self.assertEqual(1450, parse_integer("1.450"))
         self.assertEqual(1110, parse_integer("1,110"))
         self.assertEqual(15, parse_integer("15"))
diff --git a/tests/tests_world.py b/tests/tests_world.py
index d473f9d..3558b7d 100644
--- a/tests/tests_world.py
+++ b/tests/tests_world.py
@@ -25,7 +25,8 @@ FILE_WORLD_LIST_TIBIADATA_OFFLINE = "world/tibiadata_list_offline.json"
 class TestWorld(TestCommons, unittest.TestCase):
 
     # region Tibia.com Tests
-    def testWorld(self):
+    def test_world_from_content_full(self):
+        """Testing parsing a world with full information"""
         content = self._load_resource(FILE_WORLD_FULL)
         world = World.from_content(content)
 
@@ -52,7 +53,8 @@ class TestWorld(TestCommons, unittest.TestCase):
         world_json = json.loads(world_json_raw)
         self.assertEqual(len(world.online_players), len(world_json["online_players"]))
 
-    def testWorldOffline(self):
+    def test_world_from_content_offline(self):
+        """Testing parsing an offline world"""
         content = self._load_resource(FILE_WORLD_FULL_OFFLINE,)
         world = World.from_content(content)
 
@@ -75,18 +77,21 @@ class TestWorld(TestCommons, unittest.TestCase):
         self.assertEqual(len(world.online_players), world.online_count)
         self.assertEqual(World.get_url(world.name), world.url)
 
-    def testWorldNotFound(self):
+    def test_world_from_content_not_found(self):
+        """Testing parsing a world that doesn't exist"""
         content = self._load_resource(FILE_WORLD_NOT_FOUND)
         world = World.from_content(content)
 
         self.assertIsNone(world)
 
-    def testWorldUnrelated(self):
+    def test_world_from_content_unrelated_section(self):
+        """Testing parsing a world using an unrelated section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             World.from_content(content)
 
-    def testWorldTournament(self):
+    def test_world_from_content_tournament(self):
+        """Testing parsing a tournament world"""
         content = self._load_resource(FILE_WORLD_TOURNAMENT)
         world = World.from_content(content)
 
@@ -100,7 +105,8 @@ class TestWorld(TestCommons, unittest.TestCase):
     # endregion
 
     # region Tibia.com WorldOverview Tests
-    def testWorldOverview(self):
+    def test_world_overview_from_content(self):
+        """Testing parsing world overview"""
         content = self._load_resource(FILE_WORLD_LIST)
         world_overview = WorldOverview.from_content(content)
 
@@ -117,7 +123,8 @@ class TestWorld(TestCommons, unittest.TestCase):
         worlds = ListedWorld.list_from_content(content)
         self.assertEqual(len(world_overview.worlds), len(worlds))
 
-    def testWorldOverviewOffline(self):
+    def test_world_overview_from_content_offline(self):
+        """Testing parsing world overview with offline worlds"""
         content = self._load_resource(FILE_WORLD_LIST_OFFLINE)
         world_overview = WorldOverview.from_content(content)
 
@@ -130,7 +137,8 @@ class TestWorld(TestCommons, unittest.TestCase):
         self.assertIsInstance(world_overview.worlds[0].location, WorldLocation)
         self.assertIsInstance(world_overview.worlds[0].online_count, int)
 
-    def testWorldOverviewUnrelated(self):
+    def test_world_overview_from_content_unrelated(self):
+        """Testing parsing an unrealted tibia section"""
         content = self._load_resource(self.FILE_UNRELATED_SECTION)
         with self.assertRaises(InvalidContent):
             ListedWorld.list_from_content(content)
@@ -139,7 +147,8 @@ class TestWorld(TestCommons, unittest.TestCase):
 
     # region TibiaData Tests
 
-    def testWorldTibiadata(self):
+    def test_world_from_tibiadata(self):
+        """Testing parsing a world from TibiaData"""
         content = self._load_resource(FILE_WORLD_TIBIADATA)
         world = World.from_tibiadata(content)
 
@@ -162,7 +171,8 @@ class TestWorld(TestCommons, unittest.TestCase):
         self.assertEqual(len(world.online_players), world.online_count)
         self.assertEqual(World.get_url_tibiadata(world.name), world.url_tibiadata)
 
-    def testWorldTibiaDataOffline(self):
+    def test_world_from_tibiadata_offline(self):
+        """Testing parsing an offline world"""
         content = self._load_resource(FILE_WORLD_TIBIADATA_OFFLINE)
         world = World.from_tibiadata(content)
 
@@ -184,17 +194,20 @@ class TestWorld(TestCommons, unittest.TestCase):
         self.assertEqual(len(world.online_players), world.online_count)
         self.assertEqual(World.get_url_tibiadata(world.name), world.url_tibiadata)
 
-    def testWorldTibiaDataNotFound(self):
+    def test_world_from_tibiadata_not_found(self):
+        """Testing parsing a world that doesn't exist in TibiaData"""
         content = self._load_resource(FILE_WORLD_TIBIADATA_NOT_FOUND)
         world = World.from_tibiadata(content)
 
         self.assertIsNone(world)
 
-    def testWorldTibiaDataInvalidJson(self):
+    def test_world_from_tibiadata_invalid_json(self):
+        """Testing parsing an invalid json"""
         with self.assertRaises(InvalidContent):
             World.from_tibiadata("<html><b>Not a json string</b></html>")
 
-    def testWorldTibiaDataUnrelated(self):
+    def test_world_tibiadata_unrelated_section(self):
+        """Testing parsing an unrelated TibiaData section"""
         with self.assertRaises(InvalidContent):
             World.from_tibiadata(self._load_resource(tests.tests_character.FILE_CHARACTER_TIBIADATA))
 
@@ -202,7 +215,8 @@ class TestWorld(TestCommons, unittest.TestCase):
 
     # region TibiaData WorldOverview Tests
 
-    def testWorldOverviewTibiaData(self):
+    def test_world_overview_from_content(self):
+        """Testing parsing the world overview from TibiaData"""
         content = self._load_resource(FILE_WORLD_LIST_TIBIADATA)
         world_overview = WorldOverview.from_tibiadata(content)
 
@@ -216,7 +230,8 @@ class TestWorld(TestCommons, unittest.TestCase):
         self.assertIsInstance(world_overview.worlds[0].location, WorldLocation)
         self.assertIsInstance(world_overview.worlds[0].online_count, int)
 
-    def testWorldOverviewTibiaDataOffline(self):
+    def test_world_overview_from_content_offline(self):
+        """Testing parsing the world overview with offline worlds"""
         content = self._load_resource(FILE_WORLD_LIST_TIBIADATA_OFFLINE)
         worlds = ListedWorld.list_from_tibiadata(content)
 
@@ -228,12 +243,14 @@ class TestWorld(TestCommons, unittest.TestCase):
         self.assertIsInstance(worlds[0].location, WorldLocation)
         self.assertIsInstance(worlds[0].online_count, int)
 
-    def testWorldOverviewTibiaDataUnrelated(self):
+    def test_world_overview_from_content_unrelated(self):
+        """Testing parsing an unrelated json"""
         content = self._load_resource(FILE_WORLD_TIBIADATA)
         with self.assertRaises(InvalidContent):
             ListedWorld.list_from_tibiadata(content)
 
-    def testWorldOverviewTibiaDataInvalidJson(self):
+    def test_world_overview_from_content_invalid_json(self):
+        """Testing parsing an invalid json"""
         with self.assertRaises(InvalidContent):
             ListedWorld.list_from_tibiadata("<html><b>Not a json string</b></html>")
     # endregion